function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: number | string, b: number | string): number | string {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
} else if (typeof a ==='string' && typeof b ==='string') {
return a + b;
} else {
throw new Error('参数类型不匹配');
}
}
类型守卫相关误区
- 错误的类型判断导致重载函数调用不准确:
- 例如,错误地写成
if (typeof a === 'number' || typeof b === 'number'),这样的判断是不准确的。假设 a 是 number 类型,b 是 string 类型,此时这个条件满足,但这不符合我们函数重载的预期,应该是两个参数要么都为 number,要么都为 string。这样会导致函数在运行时抛出 参数类型不匹配 的错误,因为在这种错误判断下,a + b 的操作对于不同类型组合(number 和 string 相加)是不合法的,即使重载函数定义了两种正确的参数类型组合情况。
- 遗漏类型判断情况:
- 如果遗漏了对参数类型不匹配情况的判断(如
if (typeof a === 'number' && typeof b === 'number') 和 if (typeof a ==='string' && typeof b ==='string') 之外的情况),没有抛出错误。当传入的参数类型不符合预期时,比如一个 number 和一个 string,函数不会报错,但可能会得到不符合预期的结果或者运行时错误(例如在JavaScript中 1 + '2' 结果是字符串 12,这不是我们期望的 add 函数对于数字相加的行为)。
- 类型守卫与类型推断的混淆:
- 类型守卫只是在运行时确定值的类型,不能改变函数外部对参数类型的推断。例如,在函数内部通过类型守卫确定了
a 和 b 是 number 类型,但在函数外部调用处,参数依然是按照函数重载定义的联合类型(number | string)来推断的。如果在调用处依赖函数内部的类型守卫结果进行一些假设,可能会导致类型错误。比如在调用处假设 add 函数总是返回 number 类型,而实际上当传入字符串时会返回字符串类型。