为何TypeScript无法自行推断特定函数的调用结果类型?
TypeScript泛型函数返回类型推断问题解析
示例对象
const fcts = { fctNumber: () => 1, fctBoolean: () => true, }
正常工作的getFct函数
仅从fcts中选择函数的getFct能根据泛型T的值返回正确类型:
const getFct = <T extends keyof typeof fcts>(name: T) => { return fcts[name] } getFct('fctNumber') // () => number getFct('fctBoolean') // () => boolean
类型推断异常的getResult函数
但返回所选函数调用结果的getResult函数,本该返回对应函数的返回类型,TS却推断为number | boolean:
const getResult = <T extends keyof typeof fcts>(name: T) => { const fct = fcts[name] return fct() } getResult('fctNumber') // 期望number,得到number | boolean getResult('fctBoolean') // 期望boolean,得到number | boolean
修复方案:添加断言
在返回语句添加看似冗余的断言后,类型推断恢复正常:
const getResult = <T extends keyof typeof fcts>(name: T) => { const fct = fcts[name] return fct() as ReturnType<typeof fct> }
为什么断言能生效?
这是因为TS在处理泛型函数内的联合类型函数调用时,无法自动将泛型T的约束细化到具体的函数类型。当你把fcts[name]赋值给fct变量后,TS会把fct推断为(() => number) | (() => boolean)这个联合类型,调用该函数时,返回值默认会被推断为联合类型的返回值集合number | boolean,不会根据T的具体传入值去匹配对应函数的返回类型。
而as ReturnType<typeof fct>这个操作,相当于手动触发TS重新基于当前fct的具体类型(在泛型上下文里,这个类型和T绑定的具体函数类型关联)计算返回值类型。ReturnType<typeof fct>会精准提取该函数的返回类型,从而让TS输出符合预期的具体类型,而非宽泛的联合类型。
内容的提问来源于stack exchange,提问作者Hans
相关产品推荐
相关产品推荐

