TypeScript如何定义需含指定键至少一个且无多余键的对象类型
TypeScript 符合要求的Person类型实现
需求梳理
我们需要定义的Person类型需要满足以下规则:
- 可以只包含
firstName属性 - 可以只包含
lastName属性 - 可以同时包含
firstName和lastName属性 - 不允许包含任何其他额外属性
- 不允许两个属性都为空(即空对象)
实现方案
方案1:联合类型实现(最简洁,兼容性好)
直接通过联合类型枚举所有合法的字段组合,TS会自动校验多余属性:
type Person = | { firstName: string; lastName?: never } | { firstName?: never; lastName: string } | { firstName: string; lastName: string }
校验效果验证
合法输入不会报错:
// 全部合法 const p1: Person = { firstName: 'John' } const p2: Person = { lastName: 'Wayne' } const p3: Person = { firstName: 'John', lastName: 'Wayne' }
非法输入会触发TS报错:
// 报错:存在未定义的middleName属性 const p4: Person = { firstName: 'John', middleName: 'Bob', lastName: 'Wayne' } // 报错:没有匹配的类型分支 const p5: Person = {}
方案2:通用禁止额外属性写法
如果后续需要扩展字段,不想手动枚举所有组合,可以用泛型工具实现:
// 禁止额外属性的工具类型 type NoExtraProps<T> = T & Record<Exclude<string, keyof T>, never> // 定义Person的基础字段 type PersonBase = { firstName?: string lastName?: string } // 最终Person类型:禁止额外属性 + 至少存在一个字段 type Person = NoExtraProps<PersonBase> & ( { firstName: string } | { lastName: string } )
这个方案和方案1的校验效果完全一致,更适合字段较多的场景。
内容的提问来源于stack exchange,提问作者Charlie
相关产品推荐
相关产品推荐

