TypeScript联合类型属性不存在问题:如何正确定义类型?
解决TypeScript中对象与键数组的类型匹配问题
你的问题核心在于Props类型中object和keys是独立的联合类型,TypeScript无法推断出两者的关联性——它不知道当object是Foo时,keys必然是(keyof Foo)[],反之亦然。要解决这个问题,我们需要用泛型将对象类型和对应的键数组类型绑定起来,确保两者始终匹配。
完整解决方案代码
type Foo = { a: number } type Bar = { b: number } // 用泛型T约束对象类型,确保keys与T的键匹配 type Props<T extends Foo | Bar> = { object?: T | null; keys?: (keyof T)[]; } // 给泛型T设置默认值Foo,对应默认keys['a'] function myFunction<T extends Foo | Bar = Foo>({ object, keys = ['a'] as (keyof T)[] }: Props<T>) { // 现在TypeScript能推断出key必然存在于object上 const values = keys.map(key => object && object[key]); } // 正确调用示例 myFunction({ object: { a: 1 }, keys: ['a'] }); myFunction({ object: { b: 2 }, keys: ['b'] }); // 错误调用(TS会报错,符合预期) myFunction({ object: { a: 1 }, keys: ['b'] });
关键说明
- 泛型绑定关联性:通过泛型
T约束Props,让object的类型和keys的元素类型(keyof T)强绑定,确保传入的键一定属于当前对象的键集合。 - 默认值处理:给泛型
T设置默认值Foo,同时将默认keys断言为(keyof T)[],这样当调用函数不传参数时,默认走Foo类型的逻辑,符合你原来的默认值需求。 - 类型安全性:现在调用函数时,如果传入的
keys和object类型不匹配,TypeScript会直接报错,完全满足你“调用者必须传入与对象匹配的键”的要求。
扩展到任意类型
如果后续要支持更多类似Foo/Bar的类型,只需扩展泛型的约束范围即可,比如:
type Baz = { c: string, d: boolean }; // 修改泛型约束为所有需要支持的类型的联合 function myFunction<T extends Foo | Bar | Baz = Foo>({ object, keys = ['a'] as (keyof T)[] }: Props<T>) { const values = keys.map(key => object && object[key]); }
内容的提问来源于stack exchange,提问作者chitzui
相关产品推荐
相关产品推荐

