type Combinable = string | number;
function isString(param: unknown): param is string {
return typeof param === "string";
}
// 我实际期望这个函数的返回值能是T类型,但是会报错说返回的string或number与T的实例类型不匹配
// 问题1: 如何修复这个泛型函数?(不使用函数重载)
/* Type 'number' is not assignable to type 'T'.
'number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Combinable'.ts(2322) */
function add<T extends Combinable>(a: T, b: T): T {
if (isString(a)) {
// 问题2:这里为什么TS又只能确定a,b是Combinable的子类型,而不是a与b实际类型完全相同,也就是string | number
//type ta = typeof a; // 结果是 string & T === string
//type tb = typeof b; // 结果是 T 为什么TS不能确定和a一样也是string呢
return a + b;
} else {
return (a as number) + (b as number);
}
}
let a: Combinable = "123";
let b: Combinable = 123;
// 问题3:这里为何TS能推断出来a,b必须是实际上的相同类型,比如都是string或者都是number
add(a, b);
Type 'number' is not assignable to type 'T'.
'number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Combinable'.ts(2322)
我给T类型为联合类型的子类型
我想达到效果是这个add函数俩参数a,b要么同string或者同number,我想使用泛型函数解决,而不是函数重载,因为想提高自己的泛型类型水平
先说怎么改代码,下面解释问题
// 把返回类型改为Combinable 就可以了
function add<T extends Combinable>(a: T, b: T): Combinable {
问题1:上面代码;
先说问题3
问题3:泛型函数的两个参数的类型都是T,如果传如的两个参数类型不一样TS肯定会提示报错,但T要么是number要么是string,具体是什么类型由第一个参数决定,类型Combinable 可能是number或string,但不能同时是两种类型,所以如果a和b类型不同ts肯定会提示
问题2:string和number并不是Combinable的子类型,应该换种说法:Combinable类型可能是string类型可能是number类型