TypeScript可选泛型交叉场景下无属性空对象类型实现问题
解决方案
存在完全符合要求的「无任何键」的严格空对象类型,不需要Hack实现,最终代码如下:
// 定义严格空对象类型:无任何允许存在的属性 type StrictEmpty = Record<string | number | symbol, never> // 泛型默认值设置为StrictEmpty interface Handler<A extends object = StrictEmpty, B extends object = StrictEmpty> { func: (input: A & B) => void }
效果验证
所有场景均符合类型安全要求,且报错信息友好:
- 正常使用场景无报错
// 仅传入第一个泛型参数 const foo: Handler<{bar: string}> = { func: ({bar}) => console.log(bar) } // 同时传入两个泛型参数 const bar: Handler<{bar: string}, {baz: number}> = { func: ({bar, baz}) => console.log(bar, baz) }
- 非法解构直接抛出清晰的类型错误
// 解构不存在的属性rar,直接提示:Property 'rar' does not exist on type '{ bar: string; }' const errExample: Handler<{bar: string}> = { func: ({rar}) => console.log(rar) } // 不传任何泛型参数时,解构任何属性都会报错 const emptyExample: Handler = { func: ({anyKey}) => console.log(anyKey) }
原理解释
- 原生
{}类型的语义是「没有自有枚举属性的对象」,它兼容所有非null/undefined的类型,因此不会校验额外属性,不符合严格校验的需求。 Record<string | number | symbol, never>表示所有可能的对象键对应的属性值类型都是never,而never类型不存在任何有效值,因此该类型的对象不可能存在任何属性,完全符合「无任何键」的要求。
内容的提问来源于stack exchange,提问作者Carl-Dieter
相关产品推荐
相关产品推荐

