You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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'] });

关键说明

  1. 泛型绑定关联性:通过泛型T约束Props,让object的类型和keys的元素类型(keyof T)强绑定,确保传入的键一定属于当前对象的键集合。
  2. 默认值处理:给泛型T设置默认值Foo,同时将默认keys断言为(keyof T)[],这样当调用函数不传参数时,默认走Foo类型的逻辑,符合你原来的默认值需求。
  3. 类型安全性:现在调用函数时,如果传入的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 08:25:01