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-10JavaScript原型繼承_動力節(jié)點Java學院整理
這篇文章主要為大家詳細介紹了JavaScript原型繼承的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06