You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Zod中同时使用optional()与default()时类型推断异常咨询

问题解答

这是Zod的设计意图,核心原因是Zod严格区分了「输入类型」和「输出类型」:

  • optional()是对输入的约束,允许字段不存在或为undefined;
  • default()是解析阶段的逻辑,仅在调用parse()/safeParse()时,自动为缺失/undefined的字段填充默认值。

z.infer<T>默认返回的是输入类型,所以会保留undefined的可能性。

解决方法

1. 正确使用z.output获取解析后类型

你之前尝试z.output没生效,大概率是用法有误。正确写法如下:

import { z } from "zod";

const PaginationSchema = z.object({
  page: z.number().optional().default(1),
});

// 输入类型:允许page为 number | undefined
type PaginationInput = z.input<typeof PaginationSchema>;

// 输出类型:解析后page必然是 number(无undefined)
type PaginationOutput = z.output<typeof PaginationSchema>;

当你调用PaginationSchema.parse()时,返回值的类型就是PaginationOutput,page字段一定存在且为数字。

2. 调整Schema定义(可选)

如果不需要输入阶段允许undefined,可以去掉optional(),直接用default():

const PaginationSchema = z.object({
  page: z.number().default(1),
});

// 输入输出类型一致:{ page: number }(输入时不传page,解析后自动填充1)
type PaginationType = z.infer<typeof PaginationSchema>;

这种写法下,输入时如果显式传入undefined会触发校验错误,适合要求输入要么不传、要么传合法数字的场景。

替代工具

如果觉得Zod的输入输出类型区分过于繁琐,可以考虑Valibot——它的类型推断会直接反映默认值的效果,无需额外区分输入输出:

import { object, number, optional, defaultTo } from 'valibot';

const PaginationSchema = object({
  page: optional(number(), defaultTo(1)),
});

// 推断出的类型直接是 { page: number }
type PaginationType = typeof PaginationSchema['type'];

内容的提问来源于stack exchange,提问作者Diyan Slavov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:58:23