How to type the return value of SvelteKit endpoints? #2737
-
I get a TypeScript error on a lot of my SvelteKit endpoints and I'm not sure the best way to resolve it. The root issue seems to be around how the body is typed. Any tips? The endpoint works, only TypeScript complains. // test.json.ts
import type { RequestHandler } from '@sveltejs/kit';
interface TestResponse {
greeting: string;
}
export const get: RequestHandler = async function ({ query }) {
const name = query.get('name');
const obj: TestResponse = {
greeting: `Hello ${name}`
};
return {
body: obj
};
}; Error:
I've tried specifying the Body type explicitly, but I still get an error. export const get: RequestHandler<Record<string, any>, unknown, TestResponse>
I'm not sure the best way to make my |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
My take on this is that the endpoint returns either a byte array or a JSONString, which itself is a simple JSON value or an object containing other JSON values as per https://github.com/sveltejs/kit/blob/master/packages/kit/types/helper.d.ts#L13 Whatever body property you return has to be assignable to such. I guess it then comes down to what exactly you are testing and whether you trust that the JSON serialization "just works" or want to test that your type can be converted to a POJO, in which case that could be done separate to the endpoint test. Another alternative is to check that the serialized output can be correctly deserialized to match the data expected. I'm always wary of "testing types" unless I'm specifically using something like dtslint, as the whole point of TS is usually to add that safety into the compiler. So any serialization testing (going from typed to untyped) can focus instead of whether it can be round-tripped without losing anything to verify correct behavior. |
Beta Was this translation helpful? Give feedback.
-
This is a little more verbose, but let's you set the return type without TS complaining: import type { RequestHandler } from '@sveltejs/kit';
interface SampleResponse {
greeting: string;
}
type SampleResponseType = { [P in keyof SampleResponse]: SampleResponse[P] }
export const get: RequestHandler<any, unknown, SampleResponseType> = async function ({ query }) {
const name = query.get('name');
const obj: SampleResponse = {
greeting: `Hello ${name}`,
};
return {
body: obj
};
}; (you could probably make the SampleResponseType take a generic so it's reusuable for all types) |
Beta Was this translation helpful? Give feedback.
-
You will need to trick TS with a wrapper, please see #1997 (comment) for more details |
Beta Was this translation helpful? Give feedback.
You will need to trick TS with a wrapper, please see #1997 (comment) for more details