Skip to content

Instantly share code, notes, and snippets.

@GregRos
Last active August 26, 2023 14:42
Show Gist options
  • Save GregRos/c250502c88e3babb9f212be04929c2c6 to your computer and use it in GitHub Desktop.
Save GregRos/c250502c88e3babb9f212be04929c2c6 to your computer and use it in GitHub Desktop.
Meta type system: Usage Examples
// Includes RawServer, RawReply, RawRequest
export type MRaw := <
Server extends RawServerBase = RawServerDefault
Request extends RequestDefault
Reply extends ReplyDefault
RequestDefault := (RawServer extends http.Server | http2.Server ? ...)
ReplyDefault := (RawServer extends ...)
>
// Includes Logger and possibly derived types
export type MLogger := <
Logger extends FastifyBaseLogger
// Other Logger-based types go here
>
// Includes RawServer, RawReply, RawRequest, Logger, and TypeProvider
export type MCore := <
Raw: MRaw
Logger: MLogger
TypeProvider extends TypeProviderDefault
>
// This used to be a generic bag
export type RouteGeneric := <
Body: type = undefined
Querystring: type = undefined
Params: type = undefined
Headers: type = undefined
>
// Includes RouteGeneric, SchemaCompiler, and ContextConfig
export type MRouteSchema := <
Route: RouteGeneric
SchemaCompiler extends FastifySchema
ContextConfig = ContextConfigDefault
>
// This used to be RouteShorthandOptions<...8>
export interface RouteShorthandOptions<Core: MCore, Route: MRouteSchema> {
schema?: Route.SchemaCompiler
validatorCompiler?: FastifySchemaCompiler<Route.SchemaCompiler>
errorHandler?: (
this: FastifyInstance<Core>,
error: FastifyError,
request: FastifyRequest<Core, Route>,
reply: FastifyReply<Core, Route>
)
childLoggerFactory: FastifyChildLoggerFactory<Core>
}
// This used to be RouteOptions<...8>
export interface RouteOptions<Core: MCore, Route: MRouteSchema>
extends RouteShorthandOptions<Core, Route> {
// ...
}
// Used to be RouteShorthandMethod<...4>
export interface RouteShorthandMethod<
Raw: MRaw,
TypeProvider extends TypeProviderDefault
> {
<Route: MRouteSchema, Logger: MLogger>(
path: string,
opts: RouteShorthandOptions<<Raw, Logger, TypeProvider>, Route>
): FastifyInstance<<Raw, Logger, TypeProvider>>
}
// Used to be FastifyInstance<...5>
export interface FastifyInstance<Core: MCore> {
addSchema(schema: unknown): FastifyInstance<Core>
decorate: DecorationMethod<FastifyInstance<Core>>
// Used to be route<...3>
route<Route: MRouteSchema>(
opts: RouteOptions<Core, Route>
): FastifyInstance<Core>
// Used to be hasRoute<...3>
hasRoute<Route: MRouteSchema>(
opts: Pick<RouteOptions<Core, Route>, 'method' | 'url' | 'constrants'>
): boolean
get: RouteShorthandMethod<Core.Raw, Core.TypeProvider>
head: RouteShorthandMethod<Core.Raw, Core.TypeProvider>
post: RouteShorthandMethod<Core.Raw, Core.TypeProvider>
setDefaultRoute(defaultRoute: DefaultRoute<Core.Raw.Request, Core.Raw.Reply>): void;
}
// FastifyRequest is so complicated it needs a special meta type
// for its generic parameters. We're going to use this meta type
// to define various type expressions used in FastifyRequest
// as implicit structure. This separates these expressions
// from the member signatures, making them less complex
export type MRequest := <
Core: MCore
Route: MRouteSchema
// These used to be in a generic bag called RequestType
// We're going to use this
Params := UndefinedToUnknown<KeysOf<RouteGeneric.Params> extends never ? CallTypeProvider<TypeProvider, Route.SchemaCompiler['params']> : RouteGeneric.Params>
Query := UndefinedToUnknown<KeysOf<RouteGeneric.Querystring> extends never ? CallTypeProvider<TypeProvider, Route.SchemaCompiler['querystring']> : RouteGeneric.Querystring>
Headers := Core.Raw.Request["headers"] & UndefinedToUnknown<KeysOf<RouteGeneric.Headers> extends never ? CallTypeProvider<TypeProvider, Route.SchemaCompiler['headers']> : RouteGeneric.Headers>
Body := Core.Raw.Request["body"] & UndefinedToUnknown<KeysOf<RouteGeneric.Body> extends never ? CallTypeProvider<TypeProvider, Route.SchemaCompiler['body']> : RouteGeneric.Body>
Req := Core.Raw.Request & Route.Route.Headers
>
// Used to be FastifyRequest<...9>
export interface FastifyRequest<Request: MRequest> {
id: any
params: Request.Params
raw: Request.Core.Raw.Request
query: Request.Query
headers: Request.Headers
readonly req: Request.Req
log: Request.Core.Logger
body: Request.Body
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment