TypeScript?使用?Tuple?Union?聲明函數(shù)重載
問題:
TypeScript 中為函數(shù)添加多個簽名后,依然需要添加相應(yīng)的代碼來判斷并從不同的簽名參數(shù)列表中獲取對應(yīng)的參數(shù)。過去常見的寫法:
function refEventEmitter(event?: string): void;
function refEventEmitter(event: string, callback: () => void): void;
function refEventEmitter(callback: () => void): void;
function refEventEmitter(
eventOrCallback?: string | (() => void),
callback?: () => void,
): void {
let event: string | undefined;
if (typeof eventOrCallback === 'function') {
callback = eventOrCallback;
} else {
event = eventOrCallback;
}
// ...
}
這個過程因為將原有參數(shù)列表直接按序號拍平,參數(shù)之間的類型關(guān)聯(lián)需要人肉確保正確。
技巧:
這時我們可以通過使用tuple union 的參數(shù)類型,來無腦處理各種函數(shù)重載情況:
function refEventEmitter(event?: string): void;
function refEventEmitter(event: string, callback: () => void): void;
function refEventEmitter(callback: () => void): void;
function refEventEmitter(
...args:
| [event?: string]
| [
event: string,
callback: () => unknown,
]
| [callback: () => unknown]
): void {
let [event, callback] =
args.length === 2
? args
: typeof args[0] === 'function'
? [undefined, args[0]]
: [args[0], undefined];
// ...
}
實際上,此時上方的簽名列表也不再需要了:
function refEventEmitter(
...args:
| [event?: string]
| [
event: string,
callback: () => unknown,
]
| [callback: () => unknown]
): void {
let [event, callback] =
args.length === 2
? args
: typeof args[0] === 'function'
? [undefined, args[0]]
: [args[0], undefined];
// ...
}
這篇其實拖了有點久,在寫的時候發(fā)現(xiàn) TypeScript 已經(jīng)內(nèi)置了 "Convert overload list to single signature" 的重構(gòu)選項,可以一鍵將重載列表變?yōu)閰?shù) tuple union。
不過到這里其實還存在問題,TypeScript 中 typeof 條件判斷不能對整個對象進行收窄,只能收窄被 typeof 到的某個元素、屬性。上面的例子中,如果需要的不只是 args[0] 就會出現(xiàn)問題。
此時我們可以引入一個工具函數(shù) isTypeOfProperty(object, key, type):
此時實現(xiàn)就變成了:
function refEventEmitter(
...args:
| [event?: string]
| [
event: string,
callback: () => unknown,
]
| [callback: () => unknown]
): void {
let [event, callback] =
args.length === 2
? args
: isTypeOfProperty(args, 0, 'function')
? [undefined, args[0]]
: [args[0], undefined];
// ...
}到此這篇關(guān)于TypeScript 使用 Tuple Union 聲明函數(shù)重載的文章就介紹到這了,更多相關(guān)TypeScript 聲明函數(shù)重載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS實現(xiàn)頁面導(dǎo)航與內(nèi)容相互錨定實例詳解
這篇文章主要為大家介紹了JS實現(xiàn)頁面導(dǎo)航與內(nèi)容相互錨定實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10
JavaScript原型繼承_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細介紹了JavaScript原型繼承的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06

