Skip to content

Commit

Permalink
Add this types to decorator functions (#3203)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthyk committed Jul 21, 2021
1 parent 4664ce5 commit 7db55d4
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
3 changes: 3 additions & 0 deletions docs/Decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ upon "greet" and "log" decorators:
fastify.decorate('utility', fn, ['greet', 'log'])
```

Note: using an arrow function will break the binding of `this` to the
`FastifyInstance`.

If a dependency is not satisfied, the `decorate` method will throw an exception.
The dependency check is performed before the server instance is booted. Thus,
it cannot occur during runtime.
Expand Down
36 changes: 34 additions & 2 deletions test/types/instance.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import fastify, { FastifyBodyParser, FastifyError, FastifyInstance, ValidationResult } from '../../fastify'
import { expectAssignable, expectError, expectType } from 'tsd'
import fastify, {
FastifyBodyParser,
FastifyError,
FastifyInstance,
FastifyLoggerInstance,
ValidationResult
} from '../../fastify'
import { expectAssignable, expectError, expectNotAssignable, expectType } from 'tsd'
import { FastifyRequest } from '../../types/request'
import { FastifyReply } from '../../types/reply'
import { HookHandlerDoneFunction } from '../../types/hooks'
Expand Down Expand Up @@ -130,3 +136,29 @@ expectType<string>(server.printRoutes({ includeHooks: true, commonPrefix: false,
expectType<string>(server.printRoutes({ includeMeta: ['key1', Symbol('key2')] }))

expectType<string>(server.printRoutes())

server.decorate<(x: string) => void>('test', function (x: string): void {
expectType<FastifyInstance>(this)
})
server.decorate('test', function (x: string): void {
expectType<FastifyInstance>(this)
})

server.decorateRequest<(x: string, y: number) => void>('test', function (x: string, y: number): void {
expectType<FastifyRequest>(this)
})
server.decorateRequest('test', function (x: string, y: number): void {
expectType<FastifyRequest>(this)
})

server.decorateReply<(x: string) => void>('test', function (x: string): void {
expectType<FastifyReply>(this)
})
server.decorateReply('test', function (x: string): void {
expectType<FastifyReply>(this)
})

expectError(server.decorate<string>('test', true))
expectError(server.decorate<(myNumber: number) => number>('test', function (myNumber: number): string {
return ''
}))
25 changes: 21 additions & 4 deletions types/instance.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,27 @@ export interface FastifyInstance<
close(): FastifyInstance<RawServer, RawRequest, RawReply, Logger> & PromiseLike<undefined>;
close(closeListener: () => void): FastifyInstance<RawServer, RawRequest, RawReply, Logger>;

// should be able to define something useful with the decorator getter/setter pattern using Generics to enfore the users function returns what they expect it to
decorate(property: string | symbol, value: any, dependencies?: string[]): FastifyInstance<RawServer, RawRequest, RawReply, Logger>;
decorateRequest(property: string | symbol, value: any, dependencies?: string[]): FastifyInstance<RawServer, RawRequest, RawReply, Logger>;
decorateReply(property: string | symbol, value: any, dependencies?: string[]): FastifyInstance<RawServer, RawRequest, RawReply, Logger>;
// should be able to define something useful with the decorator getter/setter pattern using Generics to enforce the users function returns what they expect it to
decorate<T>(property: string | symbol,
value: T extends (...args: any[]) => any
? (this: FastifyInstance<RawServer, RawRequest, RawReply, Logger>, ...args: Parameters<T>) => ReturnType<T>
: T,
dependencies?: string[]
): FastifyInstance<RawServer, RawRequest, RawReply, Logger>;

decorateRequest<T>(property: string | symbol,
value: T extends (...args: any[]) => any
? (this: FastifyRequest, ...args: Parameters<T>) => ReturnType<T>
: T,
dependencies?: string[]
): FastifyInstance<RawServer, RawRequest, RawReply, Logger>;

decorateReply<T>(property: string | symbol,
value: T extends (...args: any[]) => any
? (this: FastifyReply, ...args: Parameters<T>) => ReturnType<T>
: T,
dependencies?: string[]
): FastifyInstance<RawServer, RawRequest, RawReply, Logger>;

hasDecorator(decorator: string | symbol): boolean;
hasRequestDecorator(decorator: string | symbol): boolean;
Expand Down

0 comments on commit 7db55d4

Please sign in to comment.