Skip to main content

类型提供者

类型提供者

¥Type Providers

类型提供程序是一种 TypeScript 功能,使 Fastify 能够从内联 JSON 模式推断类型信息。它们是在路由上指定通用参数的替代方法,可以减少在项目中为每个模式保留关联类型的需要。

¥Type Providers are a TypeScript feature that enables Fastify to infer type information from inline JSON Schema. They are an alternative to specifying generic arguments on routes and can reduce the need to keep associated types for each schema in a project.

提供者

¥Providers

官方类型提供程序包遵循 @fastify/type-provider-{provider-name} 命名约定。还有几个社区提供商可用。

¥Official Type Provider packages follow the @fastify/type-provider-{provider-name} naming convention. Several community providers are also available.

支持以下推断包:

¥The following inference packages are supported:

另请参阅每个包的类型提供程序封装器包:

¥See also the Type Provider wrapper packages for each of the packages respectively:

Json 模式到 Ts

¥Json Schema to Ts

以下设置 json-schema-to-ts 类型提供程序:

¥The following sets up a json-schema-to-ts Type Provider:

$ npm i @fastify/type-provider-json-schema-to-ts
import fastify from 'fastify'
import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts'

const server = fastify().withTypeProvider<JsonSchemaToTsProvider>()

server.get('/route', {
schema: {
querystring: {
type: 'object',
properties: {
foo: { type: 'number' },
bar: { type: 'string' },
},
required: ['foo', 'bar']
}
}
}, (request, reply) => {

// type Query = { foo: number, bar: string }
const { foo, bar } = request.query // type safe!
})

TypeBox

以下设置 TypeBox 类型提供程序:

¥The following sets up a TypeBox Type Provider:

$ npm i @fastify/type-provider-typebox
import fastify from 'fastify'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
import { Type } from '@sinclair/typebox'

const server = fastify().withTypeProvider<TypeBoxTypeProvider>()

server.get('/route', {
schema: {
querystring: Type.Object({
foo: Type.Number(),
bar: Type.String()
})
}
}, (request, reply) => {

// type Query = { foo: number, bar: string }
const { foo, bar } = request.query // type safe!
})

有关设置 AJV 以与 TypeBox 配合使用,请参阅 类型框文档

¥See the TypeBox documentation for setting up AJV to work with TypeBox.

Zod

有关 Zod 类型提供程序说明,​​请参阅 官方文档

¥See official documentation for Zod Type Provider instructions.

作用域类型提供者

¥Scoped Type-Provider

提供者类型不会在全局范围内传播。在封装使用中,可以重新映射上下文以使用一个或多个提供程序(例如,typeboxjson-schema-to-ts 可以在同一应用中使用)。

¥The provider types don't propagate globally. In encapsulated usage, one can remap the context to use one or more providers (for example, typebox and json-schema-to-ts can be used in the same application).

示例:

¥Example:

import Fastify from 'fastify'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts'
import { Type } from '@sinclair/typebox'

const fastify = Fastify()

function pluginWithTypebox(fastify: FastifyInstance, _opts, done): void {
fastify.withTypeProvider<TypeBoxTypeProvider>()
.get('/', {
schema: {
body: Type.Object({
x: Type.String(),
y: Type.Number(),
z: Type.Boolean()
})
}
}, (req) => {
const { x, y, z } = req.body // type safe
});
done()
}

function pluginWithJsonSchema(fastify: FastifyInstance, _opts, done): void {
fastify.withTypeProvider<JsonSchemaToTsProvider>()
.get('/', {
schema: {
body: {
type: 'object',
properties: {
x: { type: 'string' },
y: { type: 'number' },
z: { type: 'boolean' }
},
}
}
}, (req) => {
const { x, y, z } = req.body // type safe
});
done()
}

fastify.register(pluginWithJsonSchema)
fastify.register(pluginWithTypebox)

需要注意的是,由于类型不会全局传播,因此目前无法避免在处理多个范围时在路由上进行多次注册,如下所示:

¥It is important to note that since the types do not propagate globally, it is currently not possible to avoid multiple registrations on routes when dealing with several scopes, as shown below:

import Fastify from 'fastify'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
import { Type } from '@sinclair/typebox'

const server = Fastify().withTypeProvider<TypeBoxTypeProvider>()

server.register(plugin1) // wrong
server.register(plugin2) // correct

function plugin1(fastify: FastifyInstance, _opts, done): void {
fastify.get('/', {
schema: {
body: Type.Object({
x: Type.String(),
y: Type.Number(),
z: Type.Boolean()
})
}
}, (req) => {
// In a new scope, call `withTypeProvider` again to ensure it works
const { x, y, z } = req.body
});
done()
}

function plugin2(fastify: FastifyInstance, _opts, done): void {
const server = fastify.withTypeProvider<TypeBoxTypeProvider>()

server.get('/', {
schema: {
body: Type.Object({
x: Type.String(),
y: Type.Number(),
z: Type.Boolean()
})
}
}, (req) => {
// works
const { x, y, z } = req.body
});
done()
}

FastifyInstance + TypeProvider 的类型定义

¥Type Definition of FastifyInstance + TypeProvider

使用模块时,将 FastifyInstance 与类型提供程序泛型一起使用。请参阅下面的示例:

¥When working with modules, use FastifyInstance with Type Provider generics. See the example below:

// index.ts
import Fastify from 'fastify'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
import { registerRoutes } from './routes'

const server = Fastify().withTypeProvider<TypeBoxTypeProvider>()

registerRoutes(server)

server.listen({ port: 3000 })
// routes.ts
import { Type } from '@sinclair/typebox'
import {
FastifyInstance,
FastifyBaseLogger,
RawReplyDefaultExpression,
RawRequestDefaultExpression,
RawServerDefault
} from 'fastify'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'

type FastifyTypebox = FastifyInstance<
RawServerDefault,
RawRequestDefaultExpression<RawServerDefault>,
RawReplyDefaultExpression<RawServerDefault>,
FastifyBaseLogger,
TypeBoxTypeProvider
>;

export function registerRoutes(fastify: FastifyTypebox): void {
fastify.get('/', {
schema: {
body: Type.Object({
x: Type.String(),
y: Type.Number(),
z: Type.Boolean()
})
}
}, (req) => {
// works
const { x, y, z } = req.body
});
}