如何让TypeScript根据对象属性确定函数的精确返回类型?
解决TypeScript函数根据传入key返回精确类型的问题
要让getElementValue根据传入的key返回对应精确的value类型,我们可以通过泛型+TypeScript工具类型实现类型关联,具体方案如下:
修改后的代码
const elements = [ { key: 1, value: 'foo' }, { key: 2, value: 'bar' } ] as const; type MyElement = typeof elements[number]; // 泛型函数关联key与对应value类型 function getElementValue<K extends MyElement['key']>(key: K): Extract<MyElement, { key: K }>['value'] { // 类型断言确保element非undefined(合法key必然存在) const element = elements.find(element => element.key === key) as Extract<MyElement, { key: K }>; return element.value; } const x = getElementValue(1); // ^? const x: "foo" const y = getElementValue(2); // ^? const y: "bar" const z = getElementValue(3); // 正确触发编译错误
核心原理
- 泛型捕获具体key类型:给函数添加泛型参数
K,并约束为MyElement['key'],TypeScript会自动捕获传入的具体key值类型(比如1或2)。 - Extract工具类型筛选对应元素:
Extract<MyElement, { key: K }>会从MyElement联合类型中,筛选出key属性等于K的元素类型,再取其value属性类型,就能得到当前key对应的精确返回值类型。 - 类型断言消除undefined警告:由于传入的key都是合法存在的,我们可以断言
find返回的元素必然存在,避免TypeScript误报可能的undefined。
另一种方案:预定义键值映射类型
也可以先通过映射类型创建key到value的类型映射,再实现函数:
const elements = [ { key: 1, value: 'foo' }, { key: 2, value: 'bar' } ] as const; type MyElement = typeof elements[number]; // 预先定义key与value的映射类型 type KeyValueMap = { [E in MyElement as E['key']]: E['value'] }; function getElementValue<K extends keyof KeyValueMap>(key: K): KeyValueMap[K] { const element = elements.find(element => element.key === key) as Extract<MyElement, { key: K }>; return element.value; }
这种方式更直观,先明确键值类型关系,再让函数返回对应类型,效果与第一种方案一致。
内容的提问来源于stack exchange,提问作者Nibor
相关产品推荐
相关产品推荐

