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

显式传入类型参数T时,如何从函数参数推断对应属性值类型?

解决方案:让UpdateFieldValue显式传入T后仍保持参数类型关联

你的问题核心是:当显式传入泛型参数T时,TypeScript无法将key参数的具体值和对应的value类型绑定,导致value只能接受T所有属性类型的联合值,失去了预期的类型约束。

核心原因

原来的类型定义只给整个函数类型绑定了泛型T,显式传入T后,key会被推断为keyof T的联合类型,此时TypeScript无法追踪到具体的key对应的属性类型,自然无法约束value的类型。

两种可行的解决方案

方案一:给函数类型嵌套泛型参数K

通过新增一个泛型参数K(约束为keyof T),让调用时TypeScript能推断出具体的key,从而绑定对应的value类型:

type UpdateFieldValue<T extends Record<string, unknown>> = <K extends keyof T>(key: K, value: T[K]) => void;

使用示例:

// 显式传入目标类型T
const update: UpdateFieldValue<{ age: number, name: string }> = (key, value) => {
  // 这里可以写你的业务逻辑
};

update('name', 'Alice'); // ✅ 类型正确,value为string
update('age', 25); // ✅ 类型正确,value为number
update('name', 123); // ❌ 报错:number不能赋值给string

方案二:直接定义泛型函数(更直观)

如果不需要预先定义类型,也可以直接写泛型函数,同样支持显式传入T:

function updateFieldValue<T extends Record<string, unknown>, K extends keyof T>(key: K, value: T[K]) {
  // 实现你的更新逻辑
}

// 显式传入T,调用时自动推断K
updateFieldValue<{ age: number, name: string }>('name', 'Charlie'); // ✅
updateFieldValue<{ age: number, name: string }>('age', 35); // ✅

为什么原来的写法失效?

假设你之前的写法是这样的:

type UpdateFieldValue<T extends Record<string, unknown>> = (key: keyof T, value: T[keyof T]) => void;

当显式传入{ age: number, name: string }作为T后,key的类型是'age' | 'name',value的类型是number | string——这意味着你可以给name传number,给age传string,完全不符合你的预期。而新增K泛型后,TypeScript会在调用时将K锁定为具体的key值,从而让value的类型严格对应T[K]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:12:52