TypeScript泛型函数值比较报错:类型无重叠始终返回false的疑问
为什么TypeScript泛型函数中直接比较
arg === 5会报错? 先看两个泛型函数的例子:
第一个函数检查入参类型,运行正常:
function identity<Type> (arg: Type): Type { if (typeof(arg) === 'number') console.log('test'); return arg; }
但改成直接比较入参与具体值5时,就会触发编译错误:
function identity<Type> (arg: Type): Type { if (arg === 5) console.log('test'); return arg; }
错误提示如下:
generics.ts:2:6 - error TS2367: This condition will always return 'false' since the types 'Type' and 'number' have no overlap. 2 if (arg === 5) console.log('test') ~~~~~~~~~
原因解析
TypeScript的泛型是编译时类型检查机制,当你定义<Type>时,这个Type可以是任意类型——string、boolean、对象、自定义类型等等。编译器会考虑所有可能的Type场景:
- 如果
Type是string、boolean这类和number完全无关的类型,arg ===5必然为false; - 编译器无法提前预知你只会传入number类型的参数,因此它会判定这个条件在所有合法的
Type下都不可能成立,进而抛出错误。
而typeof(arg) === 'number'之所以没问题,是因为这是运行时类型守卫,TypeScript能识别这个判断逻辑,会在该分支内把arg的类型缩小为number,编译器明确知道这个分支只有在arg是number时才会执行,因此不会报错。
解决办法
1. 给泛型添加类型约束
限定Type必须是number或者继承自number的类型,让编译器明确Type和number存在交集:
function identity<Type extends number>(arg: Type): Type { if (arg === 5) console.log('test'); return arg; }
2. 先做类型守卫再比较
先通过typeof判断arg是number类型,再比较具体值,此时编译器能在分支内确定arg的类型为number:
function identity<Type>(arg: Type): Type { if (typeof arg === 'number' && arg === 5) console.log('test'); return arg; }
内容的提问来源于stack exchange,提问作者Emre Dilek
相关产品推荐
相关产品推荐

