函數(shù)重載
這個概念是在一些強類型語言中才有的,在JS中依據(jù)不同參數(shù)類型或參數(shù)個數(shù)執(zhí)行一些不同函數(shù)體的實現(xiàn)很常見作岖,依托于TypeScript唆垃,就會有需要用到這種聲明的地方。
關(guān)于函數(shù)重載痘儡,必須要把精確的定義放在前面辕万,最后函數(shù)實現(xiàn)時,需要使用 |
操作符或者?
操作符沉删,把所有可能的輸入類型全部包含進去渐尿,以具體實現(xiàn)。如下例子1 和 例子3
例子1
例如我們有一個add函數(shù)矾瑰,它可以接收string類型的參數(shù)進行拼接,也可以接收number類型的參數(shù)進行相加殴穴。
// 上邊是聲明
function add (arg1: string, arg2: string): string
function add (arg1: number, arg2: number): number
// 因為我們在下邊有具體函數(shù)的實現(xiàn)凉夯,所以這里并不需要添加 declare 關(guān)鍵字
// 下邊是實現(xiàn)
function add (arg1: string | number, arg2: string | number) {
// 在實現(xiàn)上我們要注意嚴格判斷兩個參數(shù)的類型是否相等货葬,而不能簡單的寫一個 arg1 + arg2
if (typeof arg1 === 'string' && typeof arg2 === 'string') {
return arg1 + arg2
} else if (typeof arg1 === 'number' && typeof arg2 === 'number') {
return arg1 + arg2
}
}
TypeScript 中的函數(shù)重載也只是多個函數(shù)的聲明,具體的邏輯還需要自己去寫人柿,他并不會真的將你的多個重名 function 的函數(shù)體進行合并
考慮如下 例子2:
interface User {
name: string;
age: number;
}
declare function test(para: User | number, flag?: boolean): number;
在這個 test 函數(shù)里隘截,我們的本意可能是當傳入?yún)?shù) para 是 User 時犀农,不傳 flag,當傳入 para 是 number 時击你,傳入 flag。TypeScript 并不知道這些鸵钝,當你傳入 para 為 User 時怠堪,flag 同樣允許你傳入:
const user = {
name: 'Jack',
age: 666
}
// 沒有報錯福压,但是與想法違背
const res = test(user, false);
使用函數(shù)重載能幫助我們實現(xiàn):
interface User {
name: string;
age: number;
}
declare function test(para: User): number;
declare function test(para: number, flag: boolean): number;
const user = {
name: 'Jack',
age: 666
};
// bingo
// Error: 參數(shù)不匹配
const res = test(user, false);
實際項目中掏秩,你可能要多寫幾步,如在 class 中:
interface User {
name: string;
age: number;
}
const user = {
name: 'Jack',
age: 123
};
class SomeClass {
/**
* 注釋 1
*/
public test(para: User): number;
/**
* 注釋 2
*/
public test(para: number, flag: boolean): number;
public test(para: User | number, flag?: boolean): number {
// 具體實現(xiàn)
return 11;
}
}
const someClass = new SomeClass();
// ok
someClass.test(user);
someClass.test(123, false);
// Error
someClass.test(123);
someClass.test(user, false);
一些不需要函數(shù)重載的場景(并不絕對荆姆,如上例子2)
函數(shù)重載的意義在于能夠讓你知道傳入不同的參數(shù)得到不同的結(jié)果蒙幻,如果傳入的參數(shù)不同,但是得到的結(jié)果(類型)卻相同胆筒,那么這里就不要使用函數(shù)重載(沒有意義)邮破。
如果函數(shù)的返回值類型相同,那么就不需要使用函數(shù)重載
function func (a: number): number
function func (a: number, b: number): number
// 像這樣的是參數(shù)個數(shù)的區(qū)別仆救,我們可以使用可選參數(shù)來代替函數(shù)重載的定義
function func (a: number, b?: number): number
// 注意第二個參數(shù)在類型前邊多了一個`?`
// 亦或是一些參數(shù)類型的區(qū)別導致的
function func (a: number): number
function func (a: string): number
// 這時我們應(yīng)該使用聯(lián)合類型來代替函數(shù)重載
function func (a: number | string): number