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

如何在TypeScript中基于两种类型推断函数参数的类型?

如何正确推断TypeScript函数参数的关联类型?

我定义了以下两种类型:

type one = {
    test1: string;
    test2: string;
    test3: string;
}

type two = {
    test3: string;
    test4: string;
}

我编写了一个函数,希望接受上述两种类型中的任意一个键作为参数:

function setId(
    key: keyof one | keyof two,
    value:
      | one[typeof key] // 此处报错 - 第10行
      | two[typeof key]
) {
    setField(value);
}

第10行出现两个错误:

Property 'test3' does not exist on type 'one'
Property 'test4' does not exist on type 'one'

由于setId函数的key参数可以是one或two类型的任意键,请问如何正确推断value参数的类型?


问题原因

原写法的核心问题是没有建立key与对应类型的关联:当key是keyof one | keyof two的联合类型时,typeof key会包含所有四个键(test1/test2/test3/test4),TypeScript会尝试对每个键去匹配one和two的属性,但one不存在test4,two不存在test1/test2,因此触发类型错误。

解决方案

可以通过泛型约束或条件类型来明确key与value的类型关联,以下是几种可行写法:

写法1:函数重载

通过重载定义两种参数组合,让TypeScript明确不同key对应的value类型:

// 重载签名:分别处理one和two的键值对
function setId<K extends keyof one>(key: K, value: one[K]): void;
function setId<K extends keyof two>(key: K, value: two[K]): void;
// 实现签名
function setId(key: keyof one | keyof two, value: string) {
    setField(value);
}

写法2:条件类型关联

利用条件类型判断key所属的类型,动态推导对应的value类型:

function setId<K extends keyof (one | two)>(
  key: K,
  value: K extends keyof one ? one[K] : two[K]
) {
  setField(value);
}

写法3:泛型约束整体类型

通过泛型限定参数属于one或two,直接关联key和对应的value类型:

function setId<T extends one | two>(key: keyof T, value: T[keyof T]) {
    setField(value);
}

// 调用示例(可手动指定泛型,或让TypeScript自动推断)
setId<one>('test1', 'abc');
setId<two>('test4', 'def');

写法4:联合键值对类型

预先定义合法的键值对联合类型,直接作为函数参数:

type ValidKeyValue = 
  | { key: keyof one; value: one[keyof one] }
  | { key: keyof two; value: two[keyof two] };

function setId({ key, value }: ValidKeyValue) {
    setField(value);
}

以上写法都能确保key和value的类型匹配,避免原有的类型错误。


内容的提问来源于stack exchange,提问作者TestYellerOP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 02:35:15