diff --git a/types/example-async.test-d.ts b/types/example-async.test-d.ts new file mode 100644 index 0000000..fe2a1cd --- /dev/null +++ b/types/example-async.test-d.ts @@ -0,0 +1,19 @@ +import { FastifyPluginAsync } from "fastify"; + +type FastifyExampleAsync = FastifyPluginAsync; + +declare namespace fastifyExampleAsync { + + export interface FastifyExampleAsyncOptions { + foo?: 'bar' + } + + export interface FastifyExampleAsyncPluginOptions extends FastifyExampleAsyncOptions { + } + export const fastifyExampleAsync: FastifyExampleAsync + export { fastifyExampleAsync as default } +} + +declare function fastifyExampleAsync(...params: Parameters): ReturnType + +export default fastifyExampleAsync diff --git a/types/example-callback.test-d.ts b/types/example-callback.test-d.ts new file mode 100644 index 0000000..c23f1de --- /dev/null +++ b/types/example-callback.test-d.ts @@ -0,0 +1,19 @@ +import { FastifyPluginCallback } from "fastify"; + +type FastifyExampleCallback = FastifyPluginCallback; + +declare namespace fastifyExampleCallback { + + export interface FastifyExampleCallbackOptions { + foo?: 'bar' + } + + export interface FastifyExampleCallbackPluginOptions extends FastifyExampleCallbackOptions { + } + export const fastifyExampleCallback: FastifyExampleCallback + export { fastifyExampleCallback as default } +} + +declare function fastifyExampleCallback(...params: Parameters): ReturnType + +export default fastifyExampleCallback diff --git a/types/plugin.d.ts b/types/plugin.d.ts index 33883d8..71f7beb 100644 --- a/types/plugin.d.ts +++ b/types/plugin.d.ts @@ -8,7 +8,9 @@ import { RawServerDefault, FastifyTypeProvider, FastifyTypeProviderDefault, + FastifyBaseLogger, } from 'fastify' +import { IncomingMessage, Server, ServerResponse } from 'http' type FastifyPlugin = typeof fastifyPlugin @@ -45,40 +47,16 @@ declare namespace fastifyPlugin { * @param fn Fastify plugin function * @param options Optional plugin options */ - declare function fastifyPlugin< - Options extends FastifyPluginOptions, - RawServer extends RawServerBase = RawServerDefault, - TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault ->( - fn: FastifyPluginAsync, - options?: fastifyPlugin.PluginMetadata -): FastifyPluginAsync; - -declare function fastifyPlugin< - Options extends FastifyPluginOptions, - RawServer extends RawServerBase = RawServerDefault, - TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault ->( - fn: FastifyPluginAsync, - options?: string -): FastifyPluginAsync; - -declare function fastifyPlugin< - Options extends FastifyPluginOptions, - RawServer extends RawServerBase = RawServerDefault, - TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault ->( - fn: FastifyPluginCallback, - options?: fastifyPlugin.PluginMetadata -): FastifyPluginCallback; declare function fastifyPlugin< - Options extends FastifyPluginOptions, - RawServer extends RawServerBase = RawServerDefault, - TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault + Options extends FastifyPluginOptions = Record, + RawServer extends RawServerBase = RawServerDefault, + TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault, + Logger extends FastifyBaseLogger = FastifyBaseLogger, + Fn extends FastifyPluginCallback | FastifyPluginAsync = FastifyPluginCallback >( - fn: FastifyPluginCallback, - options?: string -): FastifyPluginCallback; + fn: Fn extends unknown ? Fn extends (...args: any) => Promise ? FastifyPluginAsync : FastifyPluginCallback : Fn, + options?: fastifyPlugin.PluginMetadata | string +): Fn; export = fastifyPlugin diff --git a/types/plugin.test-d.ts b/types/plugin.test-d.ts index 8593c34..70ec5a7 100644 --- a/types/plugin.test-d.ts +++ b/types/plugin.test-d.ts @@ -1,8 +1,10 @@ import fastifyPlugin from '..'; -import fastify, { FastifyPluginCallback, FastifyPluginAsync, FastifyError, FastifyInstance, FastifyPluginOptions } from 'fastify'; -import { expectAssignable } from 'tsd' +import fastify, { FastifyPluginCallback, FastifyPluginAsync, FastifyError, FastifyInstance, FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger } from 'fastify'; +import { expectAssignable, expectError, expectNotType, expectType } from 'tsd' import { Server } from "node:https" import { TypeBoxTypeProvider } from "@fastify/type-provider-typebox" +import fastifyExampleCallback from './example-callback.test-d'; +import fastifyExampleAsync from './example-async.test-d'; interface Options { foo: string @@ -13,79 +15,81 @@ const testSymbol = Symbol('foobar') // Callback const pluginCallback: FastifyPluginCallback = (fastify, options, next) => { } -expectAssignable(fastifyPlugin(pluginCallback)) +expectType(fastifyPlugin(pluginCallback)) const pluginCallbackWithTypes = (fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { } expectAssignable(fastifyPlugin(pluginCallbackWithTypes)) +expectNotType(fastifyPlugin(pluginCallbackWithTypes)) expectAssignable(fastifyPlugin((fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { })) +expectNotType(fastifyPlugin((fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { })) -expectAssignable(fastifyPlugin(pluginCallback, '' )) -expectAssignable(fastifyPlugin(pluginCallback, { +expectType(fastifyPlugin(pluginCallback, '')) +expectType(fastifyPlugin(pluginCallback, { fastify: '', name: '', decorators: { - fastify: [ '', testSymbol ], - reply: [ '', testSymbol ], - request: [ '', testSymbol ] + fastify: ['', testSymbol], + reply: ['', testSymbol], + request: ['', testSymbol] }, - dependencies: [ '' ], + dependencies: [''], encapsulate: true })) const pluginCallbackWithOptions: FastifyPluginCallback = (fastify, options, next) => { - expectAssignable(options.foo) + expectType(options.foo) } -expectAssignable>(fastifyPlugin(pluginCallbackWithOptions)) +expectType>(fastifyPlugin(pluginCallbackWithOptions)) const pluginCallbackWithServer: FastifyPluginCallback = (fastify, options, next) => { - expectAssignable(fastify.server) + expectType(fastify.server) } -expectAssignable>(fastifyPlugin(pluginCallbackWithServer)) +expectType>(fastifyPlugin(pluginCallbackWithServer)) -const pluginCallbackWithTypeProvider: FastifyPluginCallback = (fastify, options, next) => {} +const pluginCallbackWithTypeProvider: FastifyPluginCallback = (fastify, options, next) => { } -expectAssignable>(fastifyPlugin(pluginCallbackWithTypeProvider)) +expectType>(fastifyPlugin(pluginCallbackWithTypeProvider)) // Async const pluginAsync: FastifyPluginAsync = async (fastify, options) => { } -expectAssignable(fastifyPlugin(pluginAsync)) +expectType(fastifyPlugin(pluginAsync)) const pluginAsyncWithTypes = async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise => { } -expectAssignable(fastifyPlugin(pluginAsyncWithTypes)) +expectType>(fastifyPlugin(pluginAsyncWithTypes)) -expectAssignable(fastifyPlugin(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise => { })) -expectAssignable(fastifyPlugin(pluginAsync, '' )) -expectAssignable(fastifyPlugin(pluginAsync, { +expectType>(fastifyPlugin(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise => { })) +expectType(fastifyPlugin(pluginAsync, '')) +expectType(fastifyPlugin(pluginAsync, { fastify: '', name: '', decorators: { - fastify: [ '', testSymbol ], - reply: [ '', testSymbol ], - request: [ '', testSymbol ] + fastify: ['', testSymbol], + reply: ['', testSymbol], + request: ['', testSymbol] }, - dependencies: [ '' ], + dependencies: [''], encapsulate: true })) const pluginAsyncWithOptions: FastifyPluginAsync = async (fastify, options) => { - expectAssignable(options.foo) + expectType(options.foo) } -expectAssignable>(fastifyPlugin(pluginAsyncWithOptions)) +expectType>(fastifyPlugin(pluginAsyncWithOptions)) const pluginAsyncWithServer: FastifyPluginAsync = async (fastify, options) => { - expectAssignable(fastify.server) + expectType(fastify.server) } -expectAssignable>(fastifyPlugin(pluginAsyncWithServer)) +expectType>(fastifyPlugin(pluginAsyncWithServer)) -const pluginAsyncWithTypeProvider: FastifyPluginAsync = async (fastify, options) => {} +const pluginAsyncWithTypeProvider: FastifyPluginAsync = async (fastify, options) => { } -expectAssignable>(fastifyPlugin(pluginAsyncWithTypeProvider)) +expectType>(fastifyPlugin(pluginAsyncWithTypeProvider)) // Fastify register @@ -100,3 +104,63 @@ server.register(fastifyPlugin(pluginAsyncWithTypes)) server.register(fastifyPlugin(pluginAsyncWithOptions)) server.register(fastifyPlugin(pluginAsyncWithServer)) server.register(fastifyPlugin(pluginAsyncWithTypeProvider)) + +// properly handling callback and async +fastifyPlugin(function (fastify, options, next) { + expectType(fastify) + expectType>(options) + expectType<(err?: Error) => void>(next) +}) + +fastifyPlugin(function (fastify, options, next) { + expectType(fastify) + expectType(options) + expectType<(err?: Error) => void>(next) +}) + +fastifyPlugin(async function (fastify, options) { + expectType(fastify) + expectType(options) +}) + +expectAssignable>(fastifyPlugin(async function (fastify: FastifyInstance, options: Options) { })) +expectNotType(fastifyPlugin(async function (fastify: FastifyInstance, options: Options) { })) + +fastifyPlugin(async function (fastify, options: Options) { + expectType(fastify) + expectType(options) +}) + +fastifyPlugin(async function (fastify, options) { + expectType(fastify) + expectType>(options) +}) + +expectError( + fastifyPlugin(async function (fastify, options: Options, next) { + expectType(fastify) + expectType(options) + }) +) +expectAssignable>(fastifyPlugin(function (fastify, options, next) { })) +expectNotType(fastifyPlugin(function (fastify, options, next) { })) + +fastifyPlugin(function (fastify, options: Options, next) { + expectType(fastify) + expectType(options) + expectType<(err?: Error) => void>(next) +}) + +expectError( + fastifyPlugin(function (fastify, options: Options, next) { + expectType(fastify) + expectType(options) + return Promise.resolve() + }) +) + +server.register(fastifyExampleCallback, { foo: 'bar' }) +expectError(server.register(fastifyExampleCallback, { foo: 'baz' })) + +server.register(fastifyExampleAsync, { foo: 'bar' }) +expectError(server.register(fastifyExampleAsync, { foo: 'baz' }))