Skip to content
/ kit Public
  • Rate limit · GitHub

    Access has been restricted

    You have triggered a rate limit.

    Please wait a few minutes before you try again;
    in some cases this may take up to an hour.

  • Notifications You must be signed in to change notification settings
  • Fork 2k

Cannot use interfaces to type endpoint outputs #1997

Closed
@JeanJPNM

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

changed the title Cannot have interfaces as endpoint outputs Cannot use interfaces to type endpoint outputs on Jul 22, 2021
benmccann

benmccann commented on Jul 23, 2021

@benmccann
Member

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

utkarshkukreti commented on Jul 23, 2021

@utkarshkukreti
Contributor

Possibly related to microsoft/TypeScript#42825?

JeanJPNM

JeanJPNM commented on Jul 23, 2021

@JeanJPNM
ContributorAuthor

This issue seems to date back to 2017 microsoft/TypeScript#15300

cristovao-trevisan

cristovao-trevisan commented on Jul 24, 2021

@cristovao-trevisan
Contributor

This can be fixed by changing

diff --git a/node_modules/@sveltejs/kit/types/endpoint.d.ts b/node_modules/@sveltejs/kit/types/endpoint.d.ts
index 2687562..1963e8d 100644
--- a/node_modules/@sveltejs/kit/types/endpoint.d.ts
+++ b/node_modules/@sveltejs/kit/types/endpoint.d.ts
@@ -8,7 +8,7 @@ type JSONValue =
 	| null
 	| Date
 	| JSONValue[]
-	| { [key: string]: JSONValue };
+	| Record<string, JSONValue>;
 
 type DefaultBody = JSONValue | Uint8Array;
 

in endpoint..d.ts

JeanJPNM

JeanJPNM commented on Jul 24, 2021

@JeanJPNM
ContributorAuthor

That is not actually a fix, typescript will give an error: error TS2456: Type alias 'JSONValue' circularly references itself.

ignatiusmb

ignatiusmb commented on Jul 27, 2021

@ignatiusmb
Member

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 than any 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

export type Typify<T> = { [K in keyof T]: Typify<T[K]> };

// for this issue
type GetOutput = Typify<{ message: string }>;
type PostOutput = Typify<{ message: string }>;
type PutOutput = PostOutput;
added
documentationImprovements or additions to documentation
and removed
bugSomething isn't working
on Jul 27, 2021
added
p2-nice-to-haveSvelteKit cannot be used by a small number of people, quality of life improvements, etc.
on Aug 4, 2021
char-khan

char-khan commented on Feb 25, 2022

@char-khan

I don't know why, but @ignatiusmb 's solution doesn't work for me.
And regardless of it, I believe JSONValue shoud be any.
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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationp2-nice-to-haveSvelteKit cannot be used by a small number of people, quality of life improvements, etc.types / typescript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Cannot use interfaces to type endpoint outputs · Issue #1997 · sveltejs/kit