TypeScript 函数重载

重载指同一个函数名对应多种"调用签名":根据传入参数的类型或个数,编译器推断出不同的返回类型。TypeScript 采用"先声明多个签名、再写一个实现"的方式实现重载,让调用方获得精确的类型提示。

1. 为什么需要重载

不重载时参数只能写成联合类型,返回值往往也退化成联合类型,调用方拿到的类型不够精确,还得自己收窄:

// 未重载:返回值是 string | number,使用前需要额外判断
function pick(a: string | number): string | number {
    return a;
}

2. 重载签名 + 实现签名

先写若干重载签名(只描述可调用形态,无函数体),最后写实现签名。实现签名的参数类型要能兼容所有重载签名,但对调用方不可见:

function convert(input: string): string;
function convert(input: number): string;
function convert(input: string | number): string {
    return String(input);
}

const s: string = convert(100);   // 数字入参也返回 string
const t: string = convert("abc");
console.log(s, t); // 输出:100 abc

3. 通过参数个数区分

不同重载可以只靠参数个数区分,实现内部逐一处理每种情况:

function area(length: number): number;               // 正方形
function area(width: number, height: number): number; // 矩形
function area(a: number, b?: number): number {
    return b === undefined ? a * a : a * b;
}
console.log(area(4));    // 输出:16
console.log(area(3, 5)); // 输出:15

4. 使用注意事项

调用时只匹配"重载签名列表",实现签名不参与匹配;签名顺序要从小到大排列,否则宽松签名会先吞掉精确调用;若返回类型相同,直接用联合类型参数即可,不必重载:

// 错误示范:实现签名必须与所有重载签名兼容
// function f(a: number): number;
// function f(a: string): string;
// function f(a: number | string): boolean { return true; } // 实现不兼容,编译报错

小结

函数重载的意义是"同一逻辑、多种调用形态、各自精确的类型"。记住三要素:先写重载签名、再写兼容的实现签名、签名按从精确到宽松的顺序排列。

笔记加载中…