ecyrbe / zodios-express

zodios express server
MIT License
55 stars 8 forks source link

I'm having trouble using Express ErrorHandler with ZodiosContext #80

Closed thelinuxlich closed 1 year ago

thelinuxlich commented 2 years ago

app in this example is a ctx.app(api)

image

Full error:

[{
    "resource": "/home/thelinuxlich/onepay/1p/packages/api/src/index.ts",
    "owner": "typescript",
    "code": "2769",
    "severity": 8,
    "message": "No overload matches this call.\n  Overload 1 of 4, '(...handlers: ZodiosRouterContextRequestHandler<ZodObject<{ user: ZodObject<{ id: ZodNumber; name: ZodString; isAdmin: ZodBoolean; }, \"strip\", ZodTypeAny, { id: number; name: string; isAdmin: boolean; }, { ...; }>; }, \"strip\", ZodTypeAny, { ...; }, { ...; }>>[]): Omit<...> & ZodiosHandlers<...>', gave the following error.\n    Argument of type 'ErrorRequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' is not assignable to parameter of type 'ZodiosRouterContextRequestHandler<ZodObject<{ user: ZodObject<{ id: ZodNumber; name: ZodString; isAdmin: ZodBoolean; }, \"strip\", ZodTypeAny, { id: number; name: string; isAdmin: boolean; }, { ...; }>; }, \"strip\", ZodTypeAny, { ...; }, { ...; }>>'.\n  Overload 2 of 4, '(handlers: ZodiosRouterContextRequestHandler<ZodObject<{ user: ZodObject<{ id: ZodNumber; name: ZodString; isAdmin: ZodBoolean; }, \"strip\", ZodTypeAny, { id: number; name: string; isAdmin: boolean; }, { ...; }>; }, \"strip\", ZodTypeAny, { ...; }, { ...; }>>[]): Omit<...> & ZodiosHandlers<...>', gave the following error.\n    Argument of type 'ErrorRequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' is not assignable to parameter of type 'ZodiosRouterContextRequestHandler<ZodObject<{ user: ZodObject<{ id: ZodNumber; name: ZodString; isAdmin: ZodBoolean; }, \"strip\", ZodTypeAny, { id: number; name: string; isAdmin: boolean; }, { ...; }>; }, \"strip\", ZodTypeAny, { ...; }, { ...; }>>[]'.\n  Overload 3 of 4, '(path: string, ...handlers: ZodiosRouterContextRequestHandler<ZodObject<{ user: ZodObject<{ id: ZodNumber; name: ZodString; isAdmin: ZodBoolean; }, \"strip\", ZodTypeAny, { id: number; name: string; isAdmin: boolean; }, { ...; }>; }, \"strip\", ZodTypeAny, { ...; }, { ...; }>>[]): Omit<...> & ZodiosHandlers<...>', gave the following error.\n    Argument of type 'ErrorRequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' is not assignable to parameter of type 'string'.",
    "source": "ts",
    "startLineNumber": 230,
    "startColumn": 9,
    "endLineNumber": 230,
    "endColumn": 21
}]
ecyrbe commented 2 years ago

Yes, error handler need to be used inline to take advantage of typesafety.

thelinuxlich commented 2 years ago

Doesn't work inline too image

ecyrbe commented 2 years ago

if you remove the type of the parameters and let inference do it's job ?

thelinuxlich commented 2 years ago

Same thing

image

ecyrbe commented 2 years ago

thank you for trying. i'll take a look into it.

thelinuxlich commented 2 years ago

Now thinking about this, if we aren't supposed to type the parameters how would it work having the routes in separate files?

Example: app.get("/transactions", transactionsGet) // how transactionsGet can have typesafety on its file?

ecyrbe commented 2 years ago

you declare a router and share it where you want to declare your get impl. But always inline the get handler. it's the same with tRPC. everything is declared inline to have typesafety and not redeclare types manually.

thelinuxlich commented 2 years ago

I'm also getting this weird error, but it doesn't stop app from typechecking

image

Full error:

[{
    "resource": "/home/thelinuxlich/onepay/1p/packages/api/src/index.ts",
    "owner": "typescript",
    "code": "2742",
    "severity": 8,
    "message": "The inferred type of 'app' cannot be named without a reference to '.pnpm/@types+express-serve-static-core@4.17.30/node_modules/@types/express-serve-static-core'. This is likely not portable. A type annotation is necessary.",
    "source": "ts",
    "startLineNumber": 30,
    "startColumn": 7,
    "endLineNumber": 30,
    "endColumn": 10
}]
ecyrbe commented 2 years ago

can you show your tsconfig.json file ?

thelinuxlich commented 2 years ago

here it is:

{
  "compilerOptions": {
    "target": "esnext",
    "composite": true,
    "incremental": true,
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "exactOptionalPropertyTypes": false,
    "allowUnreachableCode": false,
    "isolatedModules": true,
    "noUncheckedIndexedAccess": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "preserveSymlinks": false
  },
  "include": ["src/**/*", "vitest.config.ts"],
  "exclude": ["node_modules"]
}
thelinuxlich commented 2 years ago

Interesting, now that I looked the tsconfig, I changed the preserveSymlinks option to true and the error vanished(only remaining the errorHandler problem), but I don't know the effects of setting this flag to true, should it be recommended on the docs?

ecyrbe commented 2 years ago

i think the default is for it to be false. So i'll try to reproducce, diagnose and fix the issue. The only option i want to make mandatory is strict: true . i'll continue this tomorrow. thank you for the feedback loop.

thelinuxlich commented 2 years ago

Yeah, I just noticed that when preserveSymlinks is set to true it doesn't infer the app.use parameters

thelinuxlich commented 2 years ago

I also noticed that req.headers doesn't get the headers from the API definition

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

ecyrbe commented 1 year ago

Hello,

This should be fixed on version 10.4.5 of @zodios/express, thank you the reports.