TypeScript如何定义仅包含单个任意名称任意类型属性的类型?
仅允许单个属性的TypeScript类型约束实现
我们可以通过泛型条件判断实现TypeWithOnlyOneField<T>类型,约束入参只能是仅包含单个任意属性的对象,属性名、属性值类型均无限制。
类型实现代码
type TypeWithOnlyOneField<T> = keyof T extends infer K ? K extends keyof T ? Omit<T, K> extends Record<string | number | symbol, never> ? T : never : never : never
完整使用示例
import assert from 'node:assert' const myWeirdMethod = <T>(t: TypeWithOnlyOneField<T>) => { let numFields = 0 for (const key in t) { numFields++ } assert(numFields === 1) }
调用校验效果
合法调用(无类型报错)
// 字符串属性名 myWeirdMethod({ name: '测试' }) // 数字属性名 myWeirdMethod({ 100: '编号' }) // Symbol属性名 myWeirdMethod({ [Symbol('标识')]: true })非法调用(触发类型不兼容报错)
// 空对象不满足要求 myWeirdMethod({}) // 包含2个属性不满足要求 myWeirdMethod({ a: 1, b: 2 })
实现逻辑说明
- 先提取泛型T的所有键赋值给类型变量K
- 遍历每一个键K,判断移除当前键K之后的剩余对象是否为空对象
- 只有当T恰好只有1个键的时候,移除后才会得到空对象,此时返回原类型T,否则返回never
- 不符合条件的入参会因为和never类型不兼容触发报错
内容的提问来源于stack exchange,提问作者caeus
相关产品推荐
相关产品推荐

