io-ts中`t.type`与`t.strict`的区别是什么?
关于
t.strict的校验逻辑与误解澄清 核心误解:t.strict不是“禁止额外属性”
你以为t.strict会对包含未定义属性的对象抛出错误,但实际上大部分主流类型校验库的t.strict并不负责拦截额外属性——它的核心作用是强制要求schema中定义的所有属性必须存在且类型匹配,而非限制对象的“额外属性”。
与普通对象校验器的具体区别
以常用的io-ts库为例:
- 普通
t.type:仅校验schema中定义的属性是否存在、类型正确,完全忽略对象的额外属性;若schema中的属性标记为可选,还允许这些属性缺失。 t.strict:同样允许额外属性存在,但强制要求schema中所有定义的属性必须存在且类型正确——哪怕是原本标记为可选的属性,在t.strict规则下也会变成必填项。
如果你的需求是禁止对象包含额外属性,需要使用专门的“严格对象”校验器,比如io-ts中的t.exact(t.type(...)),或是zod中的z.strictObject(...)——这些工具才会在对象出现未定义属性时抛出错误。
代码示例
// 基于io-ts的示例 import * as t from 'io-ts'; // 普通type:允许额外属性,可选属性可缺失 const User = t.type({ id: t.number, name: t.string, age: t.optional(t.number) }); User.decode({ id: 1, name: 'Alice', extra: 'foo' }); // 校验成功,忽略extra字段 User.decode({ id: 1, name: 'Alice' }); // 校验成功,age为可选字段可缺失 // strict:允许额外属性,但所有定义属性必须存在(含原可选的age) const StrictUser = t.strict({ id: t.number, name: t.string, age: t.optional(t.number) }); StrictUser.decode({ id: 1, name: 'Alice', age: 25, extra: 'foo' }); // 校验成功,允许extra字段 StrictUser.decode({ id: 1, name: 'Alice' }); // 校验失败,strict规则下age必须存在 // exact:禁止额外属性,且所有定义属性必须存在 const ExactUser = t.exact(t.type({ id: t.number, name: t.string })); ExactUser.decode({ id: 1, name: 'Alice', extra: 'foo' }); // 校验失败,extra为未定义属性
内容的提问来源于stack exchange,提问作者superdave
相关产品推荐
相关产品推荐

