这是代码。
type Combinable = string | number;
function add(n: Combinable, b: Combinable) {
if (typeof n === 'string'&& typeof b ==='string') {
return n.toString() + b.toString();
} else if (typeof n === 'string'&& typeof b ==='number') {
return n.toString() + b.toString();
} else if (typeof n === 'number'&& typeof b ==='string') {
return n.toString() + b.toString();
} else {
// here raises error
// Operator '+' cannot be applied to types 'Combinable' and 'Combinable'.ts(2365)
return n + b;
}
}
// But it works fine when I change "and" operator to "or" operator.
function add(n: Combinable, b: Combinable) {
if (typeof n === 'string' || typeof b ==='string') {
return n.toString() + b.toString();
} else {
return n + b;
}
}
正如你所看到的,我在最后一行n + m
上得到了错误。
我认为如果我涵盖所有情况,它应该有效,但错误仍然存在。
我在这里错过了什么?
问题是,您在if
语句中与&&
进行的类型比较无法缩小任何单个参数的类型。
完成后
if (typeof n === 'string' && typeof b ==='string') {
TS不够聪明,无法识别这意味着n
或b
都不是字符串:n
和b
仍然被键入为Combinable
。
另一方面,使用||
使其可解析,因为可以肯定的是,在分支结束后,n
和b
都不是字符串。
修复它的一种方法是嵌套if/else:
function add(n: Combinable, b: Combinable) {
if (typeof n === 'string') {
if (typeof b === 'string') {
return n.toString() + b.toString();
} else if (typeof b === 'number') {
return n.toString() + b.toString();
}
} else if (typeof n === 'number') {
if (typeof b === 'string') {
return n.toString() + b.toString();
} else {
return n + b;
}
}
}
(也可以只使用else
而不是else if(cond)
,因为没有其他选择(
type Param = string | number;
function add(a: Param, b: Param) {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
return a.toString() + b.toString();
}
add(1, '2');
add(1, 2);
add('1', '2');