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

如何在Zod中创建Partial Record实现TypeScript运行时类型解析?

在TypeScript中使用Zod创建Partial Record实现运行时类型解析

你需要用Zod创建支持运行时校验的Partial Record类型,避免编译时正常但运行时因访问未定义属性报错的问题。

原代码存在的问题:

const ZodRecord = z.record(z.string(), z.string())
type ZodRecord = z.infer<typeof ZodRecord>

const zodRecord: ZodRecord = {
  foo: 'foo',
}
console.log(zodRecord.foo.toUpperCase())
console.log(zodRecord.bar.toUpperCase()) // 编译时无提示,运行时抛出TypeError

这段代码在编译阶段和编辑器中不会报错,但运行时访问zodRecord.bar会因undefined无法调用toUpperCase()抛出错误。

你已经知道TypeScript内置类型可以实现编译时防护:

type PartialRecord = Partial<Record<string, string>>
const partialRecord: PartialRecord = {
  foo: 'foo',
}
// console.log(partialRecord.foo.toUpperCase()) 编译时提示:partialRecord.foo is possibly 'undefined'

但需要在Zod中实现同样的效果,且因为键是运行时动态生成的,必须使用Record类型而非Zod Object的.partial()方法。


解决方案

要在Zod中创建Partial Record,只需将Record的值schema标记为可选(optional()):

import { z } from 'zod';

// 定义Zod Partial Record schema
const ZodPartialRecord = z.record(z.string(), z.string().optional());
// 推导对应的TypeScript类型
type ZodPartialRecord = z.infer<typeof ZodPartialRecord>;

// 使用示例
const partialRecord: ZodPartialRecord = {
  foo: 'foo',
};

// 编译阶段会提示:partialRecord.foo is possibly 'undefined'
// console.log(partialRecord.foo.toUpperCase()); 

// 正确用法:先判断属性是否存在
if (partialRecord.foo) {
  console.log(partialRecord.foo.toUpperCase()); // 运行时安全
}

// 运行时校验示例
const invalidData = { bar: 123 };
const result = ZodPartialRecord.safeParse(invalidData);
console.log(result.success); // false,因为bar的值不是string或undefined

原理说明

  • Zod的z.record(keySchema, valueSchema)中,将valueSchema改为z.string().optional()后,生成的类型等价于Partial<Record<string, string>>,TypeScript会自动提示属性可能为undefined。
  • 运行时Zod会校验所有存在的键对应的值必须是string类型,不存在的键则允许访问但TypeScript会做编译时防护,避免运行时错误。

内容的提问来源于stack exchange,提问作者Nyfiken Gul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:32:40