聊聊 Vue 3 中使用的函數(shù)重載有啥用?
你知道下圖中為什么定義了那么多個(gè) ref 函數(shù),它們的作用是什么?如果不清楚的話,閱讀完本文的內(nèi)容,也許你就懂了。
這是一個(gè)簡(jiǎn)單的 greet 函數(shù),它接收一個(gè)字符串類型的參數(shù),其返回值的類型也是字符串類型。
function greet(person: string): string {
return `Hello, ${person}!`;
}
當(dāng)使用字符串阿寶哥作為參數(shù)調(diào)用 greet 函數(shù)時(shí),將會(huì)返回 "Hello, 阿寶哥!"。那么現(xiàn)在問題來了,如果我們希望 greet 函數(shù)能同時(shí)支持輸入用戶列表并返回相應(yīng)的問候列表那該咋辦?
給你 3 秒鐘的時(shí)間思考一下,你想到答案了么?其中一種方案是使用聯(lián)合類型。
function greet(person: string | string[]): string | string[] {
if (typeof person === "string") {
return `Hello, ${person}!`;
} else if (Array.isArray(person)) {
return person.map((name) => `Hello, ${name}!`);
}
throw new Error("Unable to greet");
}
而另一種解決方案是使用函數(shù)重載,使用函數(shù)重載技術(shù),我們需要定義重載簽名和實(shí)現(xiàn)簽名。
其中重載簽名定義了函數(shù)中每個(gè)參數(shù)的類型和函數(shù)的返回值類型,但不包含函數(shù)體。一個(gè)函數(shù)可以有多個(gè)重載簽名。
而實(shí)現(xiàn)簽名的參數(shù)類型和返回值類型都需要使用更通用的類型,且還會(huì)包含實(shí)現(xiàn)該簽名的函數(shù)體。一個(gè)函數(shù)只能含有一個(gè)實(shí)現(xiàn)簽名。
結(jié)合了重載簽名和實(shí)現(xiàn)簽名之后,我們就實(shí)現(xiàn)了前面所說的功能:
// 重載簽名
function greet(person: string): string;
function greet(persons: string[]): string[];
// 實(shí)現(xiàn)簽名
function greet(person: unknown): unknown {
if (typeof person === 'string') {
return `Hello, ${person}!`;
} else if (Array.isArray(person)) {
return person.map(name => `Hello, ${name}!`);
}
throw new Error('Unable to greet');
}
在實(shí)際使用的過程中,只有重載簽名才是可以調(diào)用的,調(diào)用函數(shù)之后的返回值就能夠被推導(dǎo)出正確的類型。
需要注意的是,當(dāng) TypeScript 編譯器處理函數(shù)重載時(shí),它會(huì)查找重載列表,嘗試使用第一個(gè)重載定義。如果匹配的話就立即返回。當(dāng)使用實(shí)現(xiàn)簽名對(duì)應(yīng)類型的參數(shù)調(diào)用實(shí)現(xiàn)簽名函數(shù)時(shí)將會(huì)出現(xiàn)錯(cuò)誤。
除了重載普通函數(shù)之外,我們也可以對(duì)類中的方法進(jìn)行重載。方法重載是指在同一個(gè)類中方法同名,參數(shù)不同(參數(shù)類型不同、參數(shù)個(gè)數(shù)不同或參數(shù)個(gè)數(shù)相同時(shí)參數(shù)的先后順序不同),調(diào)用時(shí)根據(jù)實(shí)參的形式,選擇與它匹配的方法執(zhí)行操作的一種技術(shù)。
下面我們來看一個(gè)方法重載的例子:
class Calculator {
add(a: number, b: number): number;
add(a: string, b: string): string;
add(a: string, b: number): string;
add(a: number, b: string): string;
add(a: string | number, b: string | number) {
if (typeof a === 'string' || typeof b === 'string') {
return a.toString() + b.toString();
}
return a + b;
}
}
const calculator = new Calculator();
const result = calculator.add('Semlinker', ' Kakuqo');
閱讀完本文之后,你應(yīng)該就知道 Vue 3 響應(yīng)式模塊中的 ref 函數(shù)背后使用了什么技術(shù)。