TypeScript对象如何正确类型缩窄?keyof返回类型缩窄异常
问题原因
当前代码中key的类型被标注为keyof typeof map,即'foo' | 'bar'联合类型,TypeScript 不会基于传入的具体字面量参数自动做类型收窄,函数返回值会被推断为 map 中所有函数类型组成的联合类型:
((a: number) => number) | ((a: number, b: number) => number)
调用联合类型的函数时,TypeScript 会要求传入参数满足联合中所有成员的签名要求,也就是必须传入2个number类型参数,因此调用fn('foo')(1)时会抛出「Expected 2 arguments, but got 1」的类型错误。
修复方案
通过泛型建立入参key和返回值的类型关联,让TypeScript捕获传入的具体字面量key类型,再通过索引访问类型拿到对应key的精确值类型即可:
const map = { foo: (a: number) => a, bar: (a: number, b: number) => a + b, }; // 声明泛型K,约束为map的合法key类型 function fn<K extends keyof typeof map>(key: K) { return map[key]; } // 类型校验通过,返回值被正确推导为(a: number) => number fn('foo')(1); // 会正确做参数校验,要求传入2个number类型参数 fn('bar')(1, 2);
当传入'foo'作为参数时,泛型K会被推导为字面量类型'foo',返回值类型(typeof map)[K]会精确匹配foo对应的单参数函数类型,不会退化为函数联合类型,后续调用的参数校验会和对应函数的签名完全匹配。
内容的提问来源于stack exchange,提问作者user15163984
相关产品推荐
相关产品推荐

