TypeScript泛型疑问:字符串参数为何与数字类型不兼容?
关于TypeScript泛型
getOrDefault的类型报错解析 先看你写的代码:
function getOrDefault<T = string>(value: T, defaultValue: T, car: T): T { return value || defaultValue; } const strValue = getOrDefault("Hello", "Default", "o"); const numValue = getOrDefault(undefined, 42, "o");
报错里的"o"和42的含义
"o"是你传入第三个参数的字面量类型,它的类型就是具体的字符串"o",不是宽泛的string类型;42是第二个参数的字面量类型,TypeScript会把直接传入的具体数字识别为数字字面量类型42,而非通用的number类型。
为什么"o"没被纳入联合类型
核心原因是TypeScript泛型推断时的类型兼容性规则:
第一个调用的正常逻辑:
三个参数都是字符串字面量,它们都属于string的子类型,TypeScript可以轻松把它们合并成"Hello" | "Default" | "o"这个联合类型作为泛型T的类型,所有参数都符合这个类型,所以无报错。第二个调用的冲突逻辑:
调用getOrDefault(undefined, 42, "o")时,TS会从三个参数分别推断类型:- 第一个参数
undefined的类型是undefined - 第二个参数
42的类型是数字字面量42 - 第三个参数
"o"的类型是字符串字面量"o"
这里undefined和42可以组成兼容的联合类型undefined | 42(undefined可以和任何类型组成联合),但"o"是字符串类型,和undefined | 42完全不兼容——数字/undefined类型的变量不能赋值为字符串,所以TS不会强行把"o"纳入联合类型,反而会判定第三个参数不符合推断出的T类型,抛出报错。
- 第一个参数
替换成数字后正常的原因:
如果把第三个参数换成数字(比如100),三个参数的类型变成undefined、42、100,这三者可以组成兼容的联合类型undefined | 42 | 100,所有参数都符合这个类型,所以报错消失,新数字也会被纳入联合类型。
内容的提问来源于stack exchange,提问作者j obe
相关产品推荐
相关产品推荐

