Skip to content

Interfaces for shadow endpoints #5468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pikeas opened this issue Jul 11, 2022 · 5 comments · Fixed by #5471
Closed

Interfaces for shadow endpoints #5468

pikeas opened this issue Jul 11, 2022 · 5 comments · Fixed by #5471
Labels
documentation Improvements or additions to documentation types / typescript

Comments

@pikeas
Copy link

pikeas commented Jul 11, 2022

Describe the bug

#1997 seems to still be happening - when get() is typed as a RequestHandler and returns data defined as an interface, Typescript throws a JSONValue complaint.

Reproduction

// things.ts

import type {RequestHandler} from "@sveltejs/kit"
interface Thing {...} // JSONValue error
type Thing = {...} // no error

const things: Thing[] = [{...}, {...}]

export const get: RequestHandler = async () => {
    return {
        body: {
            things,
        },
    }
}

System Info

System:
    OS: macOS 12.3.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 82.88 MB / 16.00 GB
    Shell: 3.5.0 - /opt/homebrew/bin/fish
  Binaries:
    Node: 18.4.0 - /opt/homebrew/bin/node
    npm: 8.12.1 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 103.0.5060.114
    Firefox: 101.0.1
    Safari: 15.4
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.55
    @sveltejs/kit: next => 1.0.0-next.367
    svelte: >=3.46.0 => 3.49.0
    vite: >=2.9.13 => 2.9.14

Severity

annoyance

Additional Information

No response

@ignatiusmb
Copy link
Member

It throws an error because you didn't pass your object type through the Output generic argument, marking this as a documentation issue instead.

@ignatiusmb ignatiusmb added documentation Improvements or additions to documentation types / typescript labels Jul 12, 2022
@pikeas
Copy link
Author

pikeas commented Jul 12, 2022

Thanks for the quick response!

The next generic argument Output is used to validate the returned body from your functions by passing it through BodyValidator, which will make sure the variable in the body matches what with you assign here. It defaults to ResponseBody, which will error when body receives a custom object type.

It's not quite clear how to use Output so the handler is compatible with an interface. Could you share a code snippet for how this works?

@pikeas
Copy link
Author

pikeas commented Jul 12, 2022

interface GetOutput { things: Thing[]}
export const get: RequestHandler<Record<string, string>, GetOutput> = async () => {...}

Is this corrrect? It works but is a bit clunky in terms of DX. Also not sure what the first slot needs when using a parameterized endpoint like /things[id].ts with a generated type.

@geoffrich
Copy link
Member

I think you can do something like this using SvelteKit's generated types, which will automatically populate that first slot for parameterized endpoints:

import type { RequestHandler } from './__types/things';

interface GetOutput { things: Thing[]}

export const get: RequestHandler<GetOutput> = async function ({ request }) { }

@khromov
Copy link

khromov commented Aug 14, 2022

@geoffrich The generated types do not import for me, how do you generate them?

I did manage to make it work like @pikeas suggested, complete example:

import type { RequestHandler } from '@sveltejs/kit';

interface User {
    name: string,
}

interface PostOutput { user?: User | null }

export const POST: RequestHandler<Record<string, string>, PostOutput> = async ({ request }) => { /* OK to return { user: { name: "foo" } } */ }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation types / typescript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants