A Type Provider for json-schema-to-ts over Fastify
npm install @fastify/type-provider-json-schema-to-ts


A Type Provider for json-schema-to-ts
``bash`
npm i @fastify/type-provider-json-schema-to-ts
It is required to use TypeScript@4.3 or above withstrictnoStrictGenericChecks
mode enabled andtsconfig.json
disabled. You may take the following configuration () as an example:
`json`
{
"compilerOptions": {
"strict": true,
"noStrictGenericChecks": false
}
}
> Note
> When using plugin types, withTypeProvider is not required to register the plugin.
`tsx
const plugin: FastifyPluginAsyncJsonSchemaToTs = async function (
fastify,
_opts
) {
fastify.get(
"/",
{
schema: {
body: {
type: "object",
properties: {
x: { type: "string" },
y: { type: "number" },
z: { type: "boolean" },
},
required: ["x", "y", "z"],
} as const,
},
},
(req) => {
// The , y, and z types are automatically inferred`
const { x, y, z } = req.body;
}
);
};
You can set the FromSchema settings for things like references and deserialization for the validation and serialization schema by setting ValidatorSchemaOptions and SerializerSchemaOptions type parameters.deserialize
You can use the option in SerializerSchemaOptions to allow Date objects in place of date-time strings or other special serialization rules handled by fast-json-stringify.
`ts
const userSchema = {
type: "object",
additionalProperties: false,
properties: {
givenName: { type: "string" },
familyName: { type: "string" },
},
required: ["givenName", "familyName"],
} as const satisfies JSONSchema;
const sharedSchema = {
$id: "shared-schema",
definitions: {
user: userSchema,
},
} as const satisfies JSONSchema;
const userProfileSchema = {
$id: "userProfile",
type: "object",
additionalProperties: false,
properties: {
user: {
$ref: "shared-schema#/definitions/user",
},
joinedAt: { type: "string", format: "date-time" },
},
required: ["user", "joinedAt"],
} as const satisfies JSONSchema
type UserProfile = FromSchema
deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }]
}>;
// Use JsonSchemaToTsProvider with shared schema references
const fastify = Fastify().withTypeProvider<
JsonSchemaToTsProvider<{
ValidatorSchemaOptions: {
references: [typeof sharedSchema]
}
}>
>();
const fastify = Fastify().withTypeProvider<
JsonSchemaToTsProvider<{
ValidatorSchemaOptions: { references: [typeof sharedSchema] }
SerializerSchemaOptions: {
references: [typeof userProfileSchema]
deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }]
}
}>
>()
fastify.get(
"/profile",
{
schema: {
body: {
type: "object",
properties: {
user: {
$ref: "shared-schema#/definitions/user",
},
},
required: ['user'],
},
response: {
200: { $ref: "userProfile#" },
},
} as const,
},
(req, reply) => {
// givenName and familyName are correctly typed as strings
const { givenName, familyName } = req.body.user;
// Construct a compatible response type
const profile: UserProfile = {
user: { givenName: "John", familyName: "Doe" },
joinedAt: new Date(), // Returning a Date object
};
// A type error is surfaced if profile doesn't match the serialization schema
reply.send(profile)
}
)
`
When defining a plugin, shared schema references and deserialization options can also be used with FastifyPluginAsyncJsonSchemaToTs and FastifyPluginCallbackJsonSchemaToTs.
`ts
const schemaPerson = {
$id: "schema:person",
type: "object",
additionalProperties: false,
properties: {
givenName: { type: "string" },
familyName: { type: "string" },
joinedAt: { type: "string", format: "date-time" },
},
required: ["givenName", "familyName"],
} as const satisfies JSONSchema;
const plugin: FastifyPluginAsyncJsonSchemaToTs<{
ValidatorSchemaOptions: { references: [typeof schemaPerson] }
SerializerSchemaOptions: {
references: [typeof schemaPerson]
deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }]
};
}> = async function (fastify, _opts) {
fastify.addSchema(schemaPerson)
fastify.get(
"/profile",
{
schema: {
body: {
type: "object",
properties: {
user: {
$ref: "schema:person",
},
},
required: ['user'],
},
response: {
200: { $ref: "schema:person" },
},
}, // as const satisfies JSONSchema is not required thanks to FastifyPluginAsyncJsonSchemaToTs
},
(req, reply) => {
// givenName, familyName, and joinedAt are correctly typed as strings and validated for format.
const { givenName, familyName, joinedAt } = req.body.user;
// Send a serialized response
reply.send({
givenName: "John",
familyName: "Doe",
// Date objects form DB queries can be returned directly and transformed to string by fast-json-stringify
joinedAt: new Date(),
})
}
)
}
const callbackPlugin: FastifyPluginCallbackJsonSchemaToTs<{
ValidatorSchemaOptions: { references: [typeof schemaPerson] }
SerializerSchemaOptions: {
references: [typeof schemaPerson]
deserialize: [{ pattern: { type: "string"; format: "date-time" }; output: Date }]
};
}> = (fastify, options, done) => {
// Type check for custom options
expectType
// Schema is already added above
// fastify.addSchema(schemaPerson);
fastify.get(
"/callback-profile",
{
schema: {
body: {
type: "object",
properties: {
user: { $ref: "schema:person" },
},
required: ["user"],
},
response: {
200: { $ref: "schema:person" },
},
},
},
(req, reply) => {
const { givenName, familyName, joinedAt } = req.body.user
reply.send({
givenName,
familyName,
joinedAt: new Date(),
});
}
);
done()
};
``