Skip to content

Commit

Permalink
fix: propagate generics from FastifyRegister to plugin type (#4034)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefee committed Jun 19, 2022
1 parent cbd643f commit 45c8564
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 9 deletions.
79 changes: 77 additions & 2 deletions test/types/register.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import { expectAssignable, expectError, expectType } from 'tsd'
import fastify, { FastifyInstance, FastifyPluginAsync } from '../../fastify'
import { IncomingMessage, Server, ServerResponse } from 'http'
import { Http2Server, Http2ServerRequest, Http2ServerResponse } from 'http2'
import fastify, { FastifyInstance, FastifyError, FastifyLoggerInstance, FastifyPluginAsync, FastifyPluginCallback, FastifyPluginOptions, RawServerDefault } from '../../fastify'

const testPluginOptsAsync: FastifyPluginAsync = async function (_instance, _opts) { }
const testPluginCallback: FastifyPluginCallback = function (instance, opts, done) { }
const testPluginAsync: FastifyPluginAsync = async function (instance, opts) { }

const testPluginOpts: FastifyPluginCallback = function (instance, opts, done) { }
const testPluginOptsAsync: FastifyPluginAsync = async function (instance, opts) { }

const testPluginOptsWithType = (instance: FastifyInstance, opts: FastifyPluginOptions, done: (error?: FastifyError) => void) => { }
const testPluginOptsWithTypeAsync = async (instance: FastifyInstance, opts: FastifyPluginOptions) => { }

interface TestOptions extends FastifyPluginOptions {
option1: string;
option2: boolean;
}

// Type validation
expectError(fastify().register(testPluginOptsAsync, { prefix: 1 }))
Expand All @@ -26,3 +40,64 @@ expectAssignable<FastifyInstance>(
expectType<FastifyInstance>(instance)
})
)

// With Http2
const serverWithHttp2 = fastify({ http2: true })
type ServerWithHttp2 = FastifyInstance<Http2Server, Http2ServerRequest, Http2ServerResponse>
const testPluginWithHttp2: FastifyPluginCallback<TestOptions, Http2Server> = function (instance, opts, done) { }
const testPluginWithHttp2Async: FastifyPluginAsync<TestOptions, Http2Server> = async function (instance, opts) { }
const testPluginWithHttp2WithType = (instance: ServerWithHttp2, opts: FastifyPluginOptions, done: (error?: FastifyError) => void) => { }
const testPluginWithHttp2WithTypeAsync = async (instance: ServerWithHttp2, opts: FastifyPluginOptions) => { }
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginCallback))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginAsync))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginOpts))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginOptsAsync))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginOptsWithType))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginOptsWithTypeAsync))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginWithHttp2))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginWithHttp2Async))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginWithHttp2WithType))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(testPluginWithHttp2WithTypeAsync))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register((instance) => {
expectAssignable<FastifyInstance>(instance)
}))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register((instance: ServerWithHttp2) => {
expectAssignable<ServerWithHttp2>(instance)
}))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(async (instance) => {
expectAssignable<FastifyInstance>(instance)
}))
expectAssignable<ServerWithHttp2>(serverWithHttp2.register(async (instance: ServerWithHttp2) => {
expectAssignable<ServerWithHttp2>(instance)
}))

// With Type Provider
type TestTypeProvider = { input: 'test', output: 'test' }
const serverWithTypeProvider = fastify().withTypeProvider<TestTypeProvider>()
type ServerWithTypeProvider = FastifyInstance<Server, IncomingMessage, ServerResponse, FastifyLoggerInstance, TestTypeProvider>
const testPluginWithTypeProvider: FastifyPluginCallback<TestOptions, RawServerDefault, TestTypeProvider> = function (instance, opts, done) { }
const testPluginWithTypeProviderAsync: FastifyPluginAsync<TestOptions, RawServerDefault, TestTypeProvider> = async function (instance, opts) { }
const testPluginWithTypeProviderWithType = (instance: ServerWithTypeProvider, opts: FastifyPluginOptions, done: (error?: FastifyError) => void) => { }
const testPluginWithTypeProviderWithTypeAsync = async (instance: ServerWithTypeProvider, opts: FastifyPluginOptions) => { }
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginCallback))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginAsync))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginOpts))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginOptsAsync))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginOptsWithType))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginOptsWithTypeAsync))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginWithTypeProvider))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginWithTypeProviderAsync))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginWithTypeProviderWithType))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(testPluginWithTypeProviderWithTypeAsync))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register((instance) => {
expectAssignable<FastifyInstance>(instance)
}))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register((instance: ServerWithTypeProvider) => {
expectAssignable<ServerWithTypeProvider>(instance)
}))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(async (instance) => {
expectAssignable<FastifyInstance>(instance)
}))
expectAssignable<ServerWithTypeProvider>(serverWithTypeProvider.register(async (instance: ServerWithTypeProvider) => {
expectAssignable<ServerWithTypeProvider>(instance)
}))
16 changes: 9 additions & 7 deletions types/register.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { FastifyPluginOptions, FastifyPluginCallback, FastifyPluginAsync } from './plugin'
import { LogLevel } from './logger'
import { FastifyInstance } from './instance'
import { RawServerBase } from './utils'
import { FastifyTypeProvider, RawServerDefault } from '../fastify'

export interface RegisterOptions {
prefix?: string;
Expand All @@ -15,17 +17,17 @@ export type FastifyRegisterOptions<Options> = (RegisterOptions & Options) | ((in
*
* Function for adding a plugin to fastify. The options are inferred from the passed in FastifyPlugin parameter.
*/
export interface FastifyRegister<T = void> {
<Options extends FastifyPluginOptions>(
plugin: FastifyPluginCallback<Options>,
export interface FastifyRegister<T = void, RawServer extends RawServerBase = RawServerDefault, TypeProviderDefault extends FastifyTypeProvider = FastifyTypeProvider> {
<Options extends FastifyPluginOptions, Server extends RawServerBase = RawServer, TypeProvider extends FastifyTypeProvider = TypeProviderDefault>(
plugin: FastifyPluginCallback<Options, Server, TypeProvider>,
opts?: FastifyRegisterOptions<Options>
): T;
<Options extends FastifyPluginOptions>(
plugin: FastifyPluginAsync<Options>,
<Options extends FastifyPluginOptions, Server extends RawServerBase = RawServer, TypeProvider extends FastifyTypeProvider = TypeProviderDefault>(
plugin: FastifyPluginAsync<Options, Server, TypeProvider>,
opts?: FastifyRegisterOptions<Options>
): T;
<Options extends FastifyPluginOptions>(
plugin: FastifyPluginCallback<Options> | FastifyPluginAsync<Options> | Promise<{ default: FastifyPluginCallback<Options> }> | Promise<{ default: FastifyPluginAsync<Options> }>,
<Options extends FastifyPluginOptions, Server extends RawServerBase = RawServer, TypeProvider extends FastifyTypeProvider = TypeProviderDefault>(
plugin: FastifyPluginCallback<Options, Server, TypeProvider> | FastifyPluginAsync<Options, Server, TypeProvider> | Promise<{ default: FastifyPluginCallback<Options, Server, TypeProvider> }> | Promise<{ default: FastifyPluginAsync<Options, Server, TypeProvider> }>,
opts?: FastifyRegisterOptions<Options>
): T;
}

0 comments on commit 45c8564

Please sign in to comment.