Skip to content

Commit 754ff65

Browse files
Reorder generic parameter of FastifyRequest for ease of use (fastify#2373)
* Reorder generic parameter of FastifyRequest for ease of use * Update FastifyRequest doc to include typed request example
1 parent f65db52 commit 754ff65

13 files changed

+61
-31
lines changed

docs/TypeScript.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,8 @@ Check out the main [Learn by Example](#learn-by-example) section for detailed gu
627627

628628
#### Request
629629

630-
##### fastify.FastifyRequest<[RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RequestGeneric][FastifyRequestGenericInterface]>
631-
[src](./../types/request.d.ts#L29)
630+
##### fastify.FastifyRequest<[RequestGeneric][FastifyRequestGenericInterface], [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric]>
631+
[src](./../types/request.d.ts#L15)
632632

633633
This interface contains properties of Fastify request object. The properties added here disregard what kind of request object (http vs http2) and disregard what route level it is serving; thus calling `request.body` inside a GET request will not throw an error (but good luck sending a GET request with a body 😉).
634634

@@ -655,6 +655,15 @@ declare module 'fastify' {
655655
someProp: string
656656
}
657657
}
658+
659+
// Or you can type your request using
660+
type CustomRequest = FastifyRequest<{
661+
Body: { test: boolean };
662+
}>
663+
664+
server.get('/typedRequest', async (request: CustomRequest, reply: FastifyReply) => {
665+
return request.body.test
666+
})
658667
```
659668

660669
##### fastify.RequestGenericInterface

fastify.d.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as http2 from 'http2'
33
import * as https from 'https'
44
import * as LightMyRequest from 'light-my-request'
55

6-
import { FastifyRequest } from './types/request'
6+
import { FastifyRequest, RequestGenericInterface } from './types/request'
77
import { RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression } from './types/utils'
88
import { FastifyLoggerInstance, FastifyLoggerOptions } from './types/logger'
99
import { FastifyInstance } from './types/instance'
@@ -89,7 +89,7 @@ export type FastifyServerOptions<
8989
caseSensitive?: boolean,
9090
requestIdHeader?: string,
9191
requestIdLogLabel?: string;
92-
genReqId?: (req: FastifyRequest<RawServer, RawRequestDefaultExpression<RawServer>>) => string,
92+
genReqId?: <RequestGeneric extends RequestGenericInterface = RequestGenericInterface>(req: FastifyRequest<RequestGeneric, RawServer, RawRequestDefaultExpression<RawServer>>) => string,
9393
trustProxy?: boolean | string | string[] | number | TrustProxyFunction,
9494
querystringParser?: (str: string) => { [key: string]: string | string[] },
9595
versioning?: {
@@ -106,9 +106,9 @@ export type FastifyServerOptions<
106106
customOptions?: ajv.Options,
107107
plugins?: Function[]
108108
},
109-
frameworkErrors?: (
109+
frameworkErrors?: <RequestGeneric extends RequestGenericInterface = RequestGenericInterface>(
110110
error: FastifyError,
111-
req: FastifyRequest<RawServer, RawRequestDefaultExpression<RawServer>>,
111+
req: FastifyRequest<RequestGeneric, RawServer, RawRequestDefaultExpression<RawServer>>,
112112
res: FastifyReply<RawServer, RawRequestDefaultExpression<RawServer>, RawReplyDefaultExpression<RawServer>>
113113
) => void,
114114
rewriteUrl?: (req: RawRequestDefaultExpression<RawServer>) => string

test/types/reply.test-d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const getHandler: RouteHandlerMethod = function (_request, reply) {
77
expectType<RawReplyDefaultExpression>(reply.raw)
88
expectType<FastifyContext<ContextConfigDefault>>(reply.context)
99
expectType<FastifyLoggerInstance>(reply.log)
10-
expectType<FastifyRequest<RawServerDefault, RawRequestDefaultExpression, RequestGenericInterface>>(reply.request)
10+
expectType<FastifyRequest<RequestGenericInterface, RawServerDefault, RawRequestDefaultExpression>>(reply.request)
1111
expectType<(statusCode: number) => FastifyReply>(reply.code)
1212
expectType<(statusCode: number) => FastifyReply>(reply.status)
1313
expectType<number>(reply.statusCode)

test/types/request.test-d.ts

+21
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { expectType } from 'tsd'
22
import fastify, { RouteHandlerMethod, RawRequestDefaultExpression, RequestBodyDefault, RequestGenericInterface } from '../../fastify'
33
import { RawServerDefault, RequestParamsDefault, RequestHeadersDefault, RequestQuerystringDefault, RawReplyDefaultExpression } from '../../types/utils'
44
import { FastifyLoggerInstance } from '../../types/logger'
5+
import { FastifyRequest } from '../../types/request'
6+
import { FastifyReply } from '../../types/reply'
57

68
interface RequestBody {
79
content: string;
@@ -28,6 +30,13 @@ interface RequestData extends RequestGenericInterface {
2830

2931
type Handler = RouteHandlerMethod<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, RequestData>
3032

33+
type CustomRequest = FastifyRequest<{
34+
Body: RequestBody;
35+
Querystring: RequestQuerystring;
36+
Params: RequestParams;
37+
Headers: RequestHeaders;
38+
}>
39+
3140
const getHandler: RouteHandlerMethod = function (request, _reply) {
3241
expectType<string>(request.url)
3342
expectType<string>(request.method)
@@ -55,6 +64,18 @@ const postHandler: Handler = function (request) {
5564
expectType<string>(request.headers['x-foobar'])
5665
}
5766

67+
function putHandler(request: CustomRequest, reply: FastifyReply) {
68+
expectType<RequestBody>(request.body)
69+
expectType<RequestParams>(request.params)
70+
expectType<RequestHeaders & RawRequestDefaultExpression['headers']>(request.headers)
71+
expectType<RequestQuerystring>(request.query)
72+
expectType<string>(request.body.content)
73+
expectType<string>(request.query.from)
74+
expectType<number>(request.params.id)
75+
expectType<string>(request.headers['x-foobar'])
76+
}
77+
5878
const server = fastify()
5979
server.get('/get', getHandler)
6080
server.post('/post', postHandler)
81+
server.put('/put', putHandler)

types/content-type-parser.d.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export type FastifyBodyParser<
1414
RawServer extends RawServerBase = RawServerDefault,
1515
RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
1616
RequestGeneric extends RequestGenericInterface = RequestGenericInterface,
17-
> = ((request: FastifyRequest<RawServer, RawRequest, RequestGeneric>, rawBody: RawBody, done: ContentTypeParserDoneFunction) => void)
18-
| ((request: FastifyRequest<RawServer, RawRequest, RequestGeneric>, rawBody: RawBody) => Promise<any>)
17+
> = ((request: FastifyRequest<RequestGeneric, RawServer, RawRequest>, rawBody: RawBody, done: ContentTypeParserDoneFunction) => void)
18+
| ((request: FastifyRequest<RequestGeneric, RawServer, RawRequest>, rawBody: RawBody) => Promise<any>)
1919

2020
/**
2121
* Content Type Parser method that operates on request content
@@ -24,8 +24,8 @@ export type FastifyContentTypeParser<
2424
RawServer extends RawServerBase = RawServerDefault,
2525
RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
2626
RequestGeneric extends RequestGenericInterface = RequestGenericInterface,
27-
> = ((request: FastifyRequest<RawServer, RawRequest, RequestGeneric>, payload: RawRequest) => Promise<any>)
28-
| ((request: FastifyRequest<RawServer, RawRequest, RequestGeneric>, payload: RawRequest, done: ContentTypeParserDoneFunction) => void)
27+
> = ((request: FastifyRequest<RequestGeneric, RawServer, RawRequest>, payload: RawRequest) => Promise<any>)
28+
| ((request: FastifyRequest<RequestGeneric, RawServer, RawRequest>, payload: RawRequest, done: ContentTypeParserDoneFunction) => void)
2929

3030
/**
3131
* Natively, Fastify only supports 'application/json' and 'text/plain' content types. The default charset is utf-8. If you need to support different content types, you can use the addContentTypeParser API. The default JSON and/or plain text parser can be changed.

types/hooks.d.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export interface onRequestHookHandler<
2929
ContextConfig = ContextConfigDefault
3030
> {
3131
(
32-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
32+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
3333
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>,
3434
done: HookHandlerDoneFunction
3535
): Promise<unknown> | void;
@@ -47,7 +47,7 @@ export interface preParsingHookHandler<
4747
ContextConfig = ContextConfigDefault
4848
> {
4949
(
50-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
50+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
5151
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>,
5252
payload: RequestPayload,
5353
done: <TError extends Error = FastifyError>(err?: TError | null, res?: RequestPayload) => void
@@ -65,7 +65,7 @@ export interface preValidationHookHandler<
6565
ContextConfig = ContextConfigDefault
6666
> {
6767
(
68-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
68+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
6969
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>,
7070
done: HookHandlerDoneFunction
7171
): Promise<unknown> | void;
@@ -82,7 +82,7 @@ export interface preHandlerHookHandler<
8282
ContextConfig = ContextConfigDefault
8383
> {
8484
(
85-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
85+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
8686
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>,
8787
done: HookHandlerDoneFunction
8888
): Promise<unknown> | void;
@@ -107,7 +107,7 @@ export interface preSerializationHookHandler<
107107
ContextConfig = ContextConfigDefault
108108
> {
109109
(
110-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
110+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
111111
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>,
112112
payload: PreSerializationPayload,
113113
done: DoneFuncWithErrOrRes
@@ -127,7 +127,7 @@ export interface onSendHookHandler<
127127
ContextConfig = ContextConfigDefault
128128
> {
129129
(
130-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
130+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
131131
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>,
132132
payload: OnSendPayload,
133133
done: DoneFuncWithErrOrRes
@@ -146,7 +146,7 @@ export interface onResponseHookHandler<
146146
ContextConfig = ContextConfigDefault
147147
> {
148148
(
149-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
149+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
150150
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>,
151151
done: HookHandlerDoneFunction
152152
): Promise<unknown> | void;
@@ -167,7 +167,7 @@ export interface onErrorHookHandler<
167167
TError extends Error = FastifyError
168168
> {
169169
(
170-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
170+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
171171
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>,
172172
error: TError,
173173
done: () => void

types/instance.d.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -219,15 +219,15 @@ export interface FastifyInstance<
219219
/**
220220
* Set the 404 handler
221221
*/
222-
setNotFoundHandler(
223-
handler: (request: FastifyRequest<RawServer, RawRequest>, reply: FastifyReply<RawServer, RawRequest, RawReply>) => void
222+
setNotFoundHandler<RequestGeneric extends RequestGenericInterface = RequestGenericInterface>(
223+
handler: (request: FastifyRequest<RequestGeneric, RawServer, RawRequest>, reply: FastifyReply<RawServer, RawRequest, RawReply>) => void
224224
): void;
225225

226226
/**
227227
* Set a function that will be called whenever an error happens
228228
*/
229-
setErrorHandler<TError extends Error = FastifyError>(
230-
handler: (this: FastifyInstance<RawServer, RawRequest, RawReply, Logger>, error: TError, request: FastifyRequest<RawServer, RawRequest>, reply: FastifyReply<RawServer, RawRequest, RawReply>) => void
229+
setErrorHandler<TError extends Error = FastifyError, RequestGeneric extends RequestGenericInterface = RequestGenericInterface>(
230+
handler: (this: FastifyInstance<RawServer, RawRequest, RawReply, Logger>, error: TError, request: FastifyRequest<RequestGeneric, RawServer, RawRequest>, reply: FastifyReply<RawServer, RawRequest, RawReply>) => void
231231
): void;
232232

233233
/**

types/logger.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { FastifyError } from 'fastify-error'
22
import { RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression } from './utils'
3-
import { FastifyRequest } from './request'
3+
import { FastifyRequest, RequestGenericInterface } from './request'
44

55
/**
66
* Standard Fastify logging function
@@ -60,5 +60,5 @@ export interface FastifyLoggerOptions<
6060
};
6161
};
6262
level?: string;
63-
genReqId?: (req: FastifyRequest<RawServer, RawRequest>) => string;
63+
genReqId?: <RequestGeneric extends RequestGenericInterface = RequestGenericInterface>(req: FastifyRequest<RequestGeneric, RawServer, RawRequest>) => string;
6464
}

types/plugin.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { FastifyInstance } from './instance'
22
import { FastifyError } from 'fastify-error'
3-
import { RawServerBase, RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression } from './utils'
3+
import { RawServerBase, RawRequestDefaultExpression, RawReplyDefaultExpression } from './utils'
44

55
/**
66
* FastifyPlugin

types/reply.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export interface FastifyReply<
1717
raw: RawReply;
1818
context: FastifyContext<ContextConfig>;
1919
log: FastifyLoggerInstance;
20-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>;
20+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>;
2121
code(statusCode: number): FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>;
2222
status(statusCode: number): FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>;
2323
statusCode: number;

types/request.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ export interface RequestGenericInterface {
1313
* It defaults to http.IncomingMessage, and it also extends the relative request object.
1414
*/
1515
export interface FastifyRequest<
16+
RequestGeneric extends RequestGenericInterface = RequestGenericInterface,
1617
RawServer extends RawServerBase = RawServerDefault,
1718
RawRequest extends RawRequestDefaultExpression<RawServer> = RawRequestDefaultExpression<RawServer>,
18-
RequestGeneric extends RequestGenericInterface = RequestGenericInterface
1919
> {
2020
id: any;
2121
params: RequestGeneric['Params'];

types/route.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,6 @@ export type RouteHandlerMethod<
119119
ContextConfig = ContextConfigDefault
120120
> = (
121121
this: FastifyInstance<RawServer, RawRequest, RawReply>,
122-
request: FastifyRequest<RawServer, RawRequest, RequestGeneric>,
122+
request: FastifyRequest<RequestGeneric, RawServer, RawRequest>,
123123
reply: FastifyReply<RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>
124124
) => void | Promise<any>

types/utils.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type RawRequestDefaultExpression<
2424
RawServer extends RawServerBase = RawServerDefault
2525
> = RawServer extends http.Server | https.Server ? http.IncomingMessage
2626
: RawServer extends http2.Http2Server | http2.Http2SecureServer ? http2.Http2ServerRequest
27-
: never
27+
: never
2828

2929
/**
3030
* The default reply type based on the server type. Utilizes generic constraining.
@@ -33,7 +33,7 @@ export type RawReplyDefaultExpression<
3333
RawServer extends RawServerBase = RawServerDefault
3434
> = RawServer extends http.Server | https.Server ? http.ServerResponse
3535
: RawServer extends http2.Http2Server | http2.Http2SecureServer ? http2.Http2ServerResponse
36-
: never
36+
: never
3737

3838
export type RequestBodyDefault = unknown
3939
export type RequestQuerystringDefault = unknown

0 commit comments

Comments
 (0)