Skip to content

Commit

Permalink
Fix #4120: Defer resolution of FastifyRequestType until FastifyRequest (
Browse files Browse the repository at this point in the history
#4123)

* Defer RequestType inference until FastifyRequest property navigation

* Lint

* Remove optional ReplyType generic argument from FastifyReply

* Restore Optional Generic Argument for Request | Reply

* Comment RequestType generic argument with reference to issue
  • Loading branch information
sinclairzx81 committed Jul 21, 2022
1 parent 0ca63a0 commit f5a392b
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 125 deletions.
3 changes: 1 addition & 2 deletions test/types/hooks.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,7 @@ RawReplyDefaultExpression,
RouteGenericInterface,
ContextConfigDefault,
FastifySchema,
FastifyTypeProviderDefault,
ResolveFastifyRequestType<FastifyTypeProviderDefault, FastifySchema, RouteGenericInterface>
FastifyTypeProviderDefault
> = async function (request, reply): Promise<void> {
expectType<FastifyInstance>(this)
expectAssignable<FastifyRequest>(request)
Expand Down
2 changes: 1 addition & 1 deletion test/types/request.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const getHandler: RouteHandler = function (request, _reply) {
expectType<FastifyInstance>(request.server)
}

const getHandlerWithCustomLogger: RouteHandlerMethod<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RouteGenericInterface, ContextConfigDefault, FastifySchema, FastifyTypeProviderDefault, ResolveFastifyRequestType<FastifyTypeProviderDefault, FastifySchema, RouteGenericInterface>, CustomLoggerInterface> = function (request, _reply) {
const getHandlerWithCustomLogger: RouteHandlerMethod<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RouteGenericInterface, ContextConfigDefault, FastifySchema, FastifyTypeProviderDefault, CustomLoggerInterface> = function (request, _reply) {
expectType<CustomLoggerInterface>(request.log)
}

Expand Down
82 changes: 76 additions & 6 deletions test/types/type-provider.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import fastify, {
ContextConfigDefault, FastifySchema,
FastifyTypeProvider, RawReplyDefaultExpression,
RawRequestDefaultExpression,
RawServerDefault,
RouteHandlerMethod
FastifyTypeProvider,
HookHandlerDoneFunction,
FastifyRequest,
FastifyReply,
FastifyInstance
} from '../../fastify'
import { expectAssignable, expectError, expectType } from 'tsd'
import { IncomingHttpHeaders } from 'http'
import { Type, TSchema, Static } from '@sinclair/typebox'
import { FromSchema, JSONSchema } from 'json-schema-to-ts'
import { RouteGenericInterface } from '../../types/route'

const server = fastify()

Expand Down Expand Up @@ -437,3 +436,74 @@ expectAssignable(server.withTypeProvider<JsonSchemaToTsProvider>().get<{Reply: b
return true
}
))

// -------------------------------------------------------------------
// FastifyPlugin: Auxiliary
// -------------------------------------------------------------------

interface AuxiliaryPluginProvider extends FastifyTypeProvider { output: 'plugin-auxiliary' }

// Auxiliary plugins may have varying server types per application. Recommendation would be to explicitly remap instance provider context within plugin if required.
function plugin<T extends FastifyInstance> (instance: T) {
expectAssignable(instance.withTypeProvider<AuxiliaryPluginProvider>().get(
'/',
{
schema: { body: null }
},
(req) => {
expectType<'plugin-auxiliary'>(req.body)
}
))
}

expectAssignable(server.withTypeProvider<AuxiliaryPluginProvider>().register(plugin).get(
'/',
{
schema: { body: null }
},
(req) => {
expectType<'plugin-auxiliary'>(req.body)
}
))

// -------------------------------------------------------------------
// Handlers: Inline
// -------------------------------------------------------------------

interface InlineHandlerProvider extends FastifyTypeProvider { output: 'handler-inline' }

// Inline handlers should infer for the request parameters (non-shared)
expectAssignable(server.withTypeProvider<InlineHandlerProvider>().get(
'/',
{
onRequest: (req, res) => {
expectType<'handler-inline'>(req.body)
},
schema: { body: null }
},
(req) => {
expectType<'handler-inline'>(req.body)
}
))

// -------------------------------------------------------------------
// Handlers: Auxiliary
// -------------------------------------------------------------------

interface AuxiliaryHandlerProvider extends FastifyTypeProvider { output: 'handler-auxiliary' }

// Auxiliary handlers are likely shared for multiple routes and thus should infer as unknown due to potential varying parameters
function auxiliaryHandler (request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction): void {
expectType<unknown>(request.body)
}

expectAssignable(server.withTypeProvider<AuxiliaryHandlerProvider>().get(
'/',
{
onRequest: auxiliaryHandler,
schema: { body: null }
},
(req) => {
expectType<'handler-auxiliary'>(req.body)
}
))
58 changes: 19 additions & 39 deletions types/hooks.d.ts

Large diffs are not rendered by default.

58 changes: 19 additions & 39 deletions types/instance.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ import {
FastifySerializerCompiler
} from './schema'
import {
FastifyRequestType,
FastifyTypeProvider,
FastifyTypeProviderDefault,
ResolveFastifyRequestType
FastifyTypeProviderDefault
} from './type-provider'
import { ContextConfigDefault, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerBase, RawServerDefault } from './utils'

Expand Down Expand Up @@ -200,22 +198,20 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onRequest',
hook: onRequestHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onRequestHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onRequest',
hook: onRequestAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onRequestAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

/**
Expand All @@ -226,22 +222,20 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'preParsing',
hook: preParsingHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: preParsingHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'preParsing',
hook: preParsingAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: preParsingAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

/**
Expand All @@ -251,22 +245,20 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'preValidation',
hook: preValidationHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: preValidationHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'preValidation',
hook: preValidationAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: preValidationAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

/**
Expand All @@ -276,22 +268,20 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'preHandler',
hook: preHandlerHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: preHandlerHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'preHandler',
hook: preHandlerAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: preHandlerAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

/**
Expand All @@ -303,23 +293,21 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'preSerialization',
hook: preSerializationHookHandler<PreSerializationPayload, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: preSerializationHookHandler<PreSerializationPayload, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
PreSerializationPayload = unknown,
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'preSerialization',
hook: preSerializationAsyncHookHandler<PreSerializationPayload, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: preSerializationAsyncHookHandler<PreSerializationPayload, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

/**
Expand All @@ -331,23 +319,21 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onSend',
hook: onSendHookHandler<OnSendPayload, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onSendHookHandler<OnSendPayload, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
OnSendPayload = unknown,
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onSend',
hook: onSendAsyncHookHandler<OnSendPayload, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onSendAsyncHookHandler<OnSendPayload, RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

/**
Expand All @@ -358,22 +344,20 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onResponse',
hook: onResponseHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onResponseHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onResponse',
hook: onResponseAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onResponseAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

/**
Expand All @@ -384,22 +368,20 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onTimeout',
hook: onTimeoutHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onTimeoutHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onTimeout',
hook: onTimeoutAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onTimeoutAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

/**
Expand All @@ -412,22 +394,20 @@ export interface FastifyInstance<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onError',
hook: onErrorHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, FastifyError, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onErrorHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, FastifyError, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

addHook<
RouteGeneric extends RouteGenericInterface = RouteGenericInterface,
ContextConfig = ContextConfigDefault,
SchemaCompiler extends FastifySchema = FastifySchema,
RequestType extends FastifyRequestType = ResolveFastifyRequestType<TypeProvider, SchemaCompiler, RouteGeneric>,
Logger extends FastifyLoggerInstance = FastifyLoggerInstance
>(
name: 'onError',
hook: onErrorAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, FastifyError, SchemaCompiler, TypeProvider, RequestType, Logger>
hook: onErrorAsyncHookHandler<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, FastifyError, SchemaCompiler, TypeProvider, Logger>
): FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider>;

// Application addHooks
Expand Down

0 comments on commit f5a392b

Please sign in to comment.