Closed
Description
Describe the bug
When setting up and endpoint with typescript, it is not possible to have interfaces as endpoint outputs
Reproduction
// can be any endpoint
import type { RequestHandler } from '@sveltejs/kit';
type GetOutput = {
message: string;
};
interface PostOutput {
message: string;
}
type PutOutput = PostOutput;
// works
export const get: RequestHandler<unknown, unknown, GetOutput> = async () => {
return {
status: 200,
body: {
message: 'hello world',
},
};
};
// complains
export const post: RequestHandler<unknown, unknown, PostOutput> = async () => {
return {
status: 200,
body: {
message: 'hello world',
},
};
};
// complains
export const put: RequestHandler<unknown, unknown, PutOutput> = async () => {
return {
status: 200,
body: {
message: 'hello world',
},
};
};
Logs
src/routes/demo.ts:20:53 - error TS2344: Type 'PostOutput' does not satisfy the constraint 'DefaultBody'.
Type 'PostOutput' is not assignable to type '{ [x: string]: JSONValue; }'.
Index signature is missing in type 'PostOutput'.
20 export const post: RequestHandler<unknown, unknown, PostOutput> = async () => {
~~~~~~~~~~
src/routes/demo.ts:30:52 - error TS2344: Type 'PostOutput' does not satisfy the constraint 'DefaultBody'.
30 export const put: RequestHandler<unknown, unknown, PutOutput> = async () => {
~~~~~~~~~
Found 2 errors.
System Info
System:
OS: Windows 10 10.0.19043
CPU: (4) x64 Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
Memory: 375.01 MB / 3.89 GB
Binaries:
Node: 14.14.0 - C:\Program Files\nodejs\node.EXE
npm: 6.14.8 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 92.0.4515.107
Edge: Spartan (44.19041.1023.0), Chromium (91.0.864.71)
Internet Explorer: 11.0.19041.1
npmPackages:
@sveltejs/adapter-node: ^1.0.0-next.35 => 1.0.0-next.35
@sveltejs/kit: ^1.0.0-next.136 => 1.0.0-next.136
svelte: ^3.40.1 => 3.40.1
vite: ^2.4.3 => 2.4.3
Severity
blocking an upgrade
Additional Information
The issue is inside the JSONValue
type, using it seems to require all the types assigned to it to have string indexes, can be worked around by using the unsafe any
type, which defeats the whole purpose of having a typed endpoint
Activity
benmccann commentedon Jul 23, 2021
I'm not sure I'm enough of a TypeScript expert to know how to fix this, but I agree it's an issue. If you want to send a PR, I'd merge a fix for this
utkarshkukreti commentedon Jul 23, 2021
Possibly related to microsoft/TypeScript#42825?
JeanJPNM commentedon Jul 23, 2021
This issue seems to date back to 2017 microsoft/TypeScript#15300
cristovao-trevisan commentedon Jul 24, 2021
This can be fixed by changing
in endpoint..d.ts
JeanJPNM commentedon Jul 24, 2021
That is not actually a fix, typescript will give an error:
error TS2456: Type alias 'JSONValue' circularly references itself.
ignatiusmb commentedon Jul 27, 2021
This is somewhat a limitation from TypeScript itself -- we want any JSON values to be valid, but can't really properly type it and the current
type JSONValue
is the best one we can use (microsoft/TypeScript#1897). It is still better thanany
type, which would not guard against the changes from #1382.Unfortunately, the fix/workaround right now needs to happen on the user side, but it's pretty simple and won't take too long. Pass in any interface that is going to be returned in the endpoint through the interface below, and it should trick TS while still retaining any property inference
char-khan commentedon Feb 25, 2022
I don't know why, but @ignatiusmb 's solution doesn't work for me.And regardless of it, I believe
JSONValue
shoud beany
.It is redundant to do type manipulation to make sure it is serializable, and I also think that passing value that cannot be serialized for server-side use should be allowed.
UPDATE:
sry, it works, but my thought haven't changed.
9 remaining items