-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Return type not correctly set with type providers #4088
Comments
cc @sinclairzx81 as you did #3524 It appears that if you inline export type RouteHandlerMethod<
RawServer extends RawServerBase = RawServerDefault,
RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
RawReply extends RawReplyDefaultExpression<RawServer> = RawReplyDefaultExpression<RawServer>,
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
// ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
> = (
this: FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>,
request: FastifyRequest<RouteGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider, ContextConfig, RequestType, Logger>,
reply: FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>
) => ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric> I'm not at all sure why this would happen. |
This is the same as fastify/fastify-type-provider-json-schema-to-ts#12, right? |
I don't think so. The minimum reproduction I provided does not use json schema (nor the type provider in the issue), the original codebase I found this in uses a home-made zod type provider, the issue is only about return type ( |
@A5rocks Hi! Just had a quick look into this. As you mentioned, inlining the Test RouteHandlerMethodexport type RouteHandlerMethod<
RawServer extends RawServerBase = RawServerDefault,
RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
RawReply extends RawReplyDefaultExpression<RawServer> = RawReplyDefaultExpression<RawServer>,
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
ReturnType = ResolveFastifyReplyReturnType<TypeProvider, SchemaCompiler, RouteGeneric>,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
> = (
this: FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>,
request: FastifyRequest<RouteGeneric, RawServer, RawRequest, SchemaCompiler, TypeProvider, ContextConfig, RequestType, Logger>,
reply: FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>,
test: ReturnType // 1) When the return type is used as an argument, TS must eagerly resolve the type.
) => ReturnType // 2) Because the type is known on the argument. This now works Exampleinterface TestProvider extends FastifyTypeProvider { output: string }
fastify().withTypeProvider<TestProvider>().get('/', {
schema: {
response: {
200: ''
}
}
}, (req, res, test) => { // test is 'string | void | Promise<string | void>'
return 1 // error: test type is known. so return type is also known.
}) ResolutionI think probably the easiest solution here is to go with inlining the return type (as per your example), but perhaps with some comments left around TS's inference behavior for the generic return type. @A5rocks Would you be interested in submitting a PR for the inline? @RafaelGSS I think this inference behavior might be a signal to consider a refactor on the In this regard, because the It may be good to defer this refactor for the time being however, as I think it would share some cross over with "status code narrowing" that was briefly mentioned in the past. For the time being the solution to inline the return type (as per @A5rocks Hope that helps! |
This might be fixed in #4089. @sinclairzx81 Could you check that out? (Along with #4076 which is already merged, but also changes type-provider linked things). |
@A5rocks #4089 looks good to me :) As for #4076, this also looks good too. Note: The server.get('/', {
schema: {
response: {
200: { type: 'string' }, // keyof: 200 | 500
500: { type: 'number' }
}
}
}, (req, res) => {
return res.send('hello') // ok: string | number
return res.send(10) // ok: string | number
return res.status(200).send('hello') // ok: string
return res.status(500).send('hello') // fail: expect number
^ narrow here
}) There is a little bit of crossover between the status codes, return types and response types. But the #4089 should help carry things through until such time as the status code narrowing work gets some focus. Good work! |
Prerequisites
Fastify version
4.1.0
Plugin version
No response
Node.js version
16.14.0
Operating system
Windows
Operating system version (i.e. 20.04, 11.3, 10)
11
Description
Return types aren't being checked correctly when inferred by a type provider.
Steps to Reproduce
Expected Behavior
I expect
return { foo: 555 }
to error, because it's notreturn "some string"
or the like.The text was updated successfully, but these errors were encountered: