编译期类型不是防弹衣
TypeScript 很强,但它无法保证运行时数据一定符合类型。只要数据来自网络、表单、消息队列,就需要校验。
一个常见坑
type User = { id: string; age: number }
function handleUser(u: User) {
return u.age + 1
}
如果后端把 age 传成字符串,编译不会报错,运行才炸。
用 Zod 建立输入防线
import { z } from "zod"
const UserSchema = z.object({
id: z.string().min(1),
age: z.number().int().nonnegative(),
})
type User = z.infer<typeof UserSchema>
function parseUser(input: unknown): User {
return UserSchema.parse(input)
}
好处是:
- 校验规则集中管理
- 报错信息可读
- 类型与校验规则同步
在 API 层统一拦截
建议在 BFF 或网关层就完成 parse,业务层只接收已验证的数据。这样能显著减少线上脏数据导致的连锁异常。
小结
TS 负责编译期,Zod 负责运行时。两者结合,才能让类型安全真正落地。