在 TypeScript 中,函數重載(Function Overload)?是指為同一個函數提供多個不同的調用簽名(參數類型和返回值類型的組合),但函數體只有一個實現。這樣可以讓函數在不同的輸入下表現出不同的行為,同時保持類型安全。
一、函數重載的基本概念
1.?重載簽名(Overload Signatures)
聲明函數可以接受的不同參數類型和返回值類型,但不包含函數體。
2.?實現簽名(Implementation Signature)
實際的函數實現,參數類型必須兼容所有重載簽名,返回值類型也需符合重載簽名的約束。
二、示例:函數重載的使用
1.?基礎重載示例
typescript
// 重載簽名 1:接受數字,返回數字的平方
function calculate(x: number): number;// 重載簽名 2:接受字符串,返回字符串的長度
function calculate(x: string): number;// 實現簽名:兼容所有重載簽名
function calculate(x: number | string): number {if (typeof x === 'number') {return x * x; // 處理數字} else {return x.length; // 處理字符串}
}// 使用示例
const result1 = calculate(5); // 返回 25(數字)
const result2 = calculate("abc"); // 返回 3(字符串長度)
// const result3 = calculate(true); // 錯誤:不匹配任何重載簽名
2.?多個參數的重載
typescript
// 重載簽名 1:合并兩個字符串
function merge(a: string, b: string): string;// 重載簽名 2:合并兩個數組
function merge(a: number[], b: number[]): number[];// 實現簽名
function merge(a: string | number[], b: string | number[]): string | number[] {if (typeof a === 'string' && typeof b === 'string') {return a + b; // 字符串拼接} else if (Array.isArray(a) && Array.isArray(b)) {return [...a, ...b]; // 數組合并}throw new Error("Invalid arguments");
}// 使用示例
const mergedStr = merge("Hello", "World"); // 返回 "HelloWorld"
const mergedArr = merge([1, 2], [3, 4]); // 返回 [1, 2, 3, 4]
三、函數重載的注意事項
-
重載簽名與實現簽名的關系
- 實現簽名的參數類型必須是所有重載簽名參數類型的超集。
- 實現簽名的返回值類型必須能賦值給所有重載簽名的返回值類型。
typescript
// 錯誤示例:實現簽名的參數類型不兼容重載簽名 function add(a: number, b: number): number; function add(a: string, b: string): string; function add(a: number | string, b: number): number | string { // 錯誤:第二個參數必須兼容 stringreturn a + b; }
-
重載解析規則
- TypeScript 會從上到下匹配第一個符合參數類型的重載簽名。
- 因此,重載簽名的順序很重要,通常應將更具體的簽名放在前面。
typescript
function fn(x: string): string; function fn(x: any): any; function fn(x: any): any { return x; }fn("hello"); // 匹配第一個重載(更具體) fn(123); // 匹配第二個重載
四、替代方案:聯合類型與泛型
對于簡單的函數重載場景,可以使用聯合類型或泛型替代,使代碼更簡潔:
1.?聯合類型
typescript
function calculate(x: number | string): number {if (typeof x === 'number') {return x * x;} else {return x.length;}
}
2.?泛型
typescript
function identity<T>(arg: T): T {return arg;
}
五、函數重載的應用場景
-
根據參數類型返回不同類型
typescript
function parseJSON(json: string): any; function parseJSON(json: null): null; function parseJSON(json: string | null): any | null {return json ? JSON.parse(json) : null; }
-
可選參數的不同組合
typescript
function createElement(tag: string): HTMLElement; function createElement(tag: string, className: string): HTMLElement; function createElement(tag: string, className?: string): HTMLElement {const el = document.createElement(tag);if (className) el.className = className;return el; }
總結
特性 | 說明 |
---|---|
定義方式 | 先聲明多個重載簽名,再實現一個兼容所有簽名的函數體。 |
類型檢查 | 調用時必須匹配某個重載簽名,實現簽名內部需自行處理類型邏輯。 |
適用場景 | 函數需要根據不同參數類型返回不同類型,或處理多種參數組合。 |
替代方案 | 簡單場景可使用聯合類型或泛型,但函數重載能提供更精確的類型控制。 |
函數重載是 TypeScript 增強函數類型表達力的重要工具,合理使用可以讓代碼既安全又靈活。