
jsdoc也叫文檔注釋,是JS開發中的一把利器,主要用于為JS添加類型聲明,這樣我們就可以像寫TS一樣寫JS了。
我之前寫過一篇文章,講述了jsdoc的基礎用法。本篇文章,我們來看一個高級點的用法。我們來實現一個功能:根據函數的第一個參數,來確定剩余參數怎么傳。
我想實現如下函數,該函數用于向父窗口發送消息。它可以接收不確定個數的參數,其中第一個參數是eventType,該參數有固定的幾個可選值,剩余參數根據eventType的值來確定。
const sendEventToParentWindow = (eventType, ...args) => {
window.postMessage(
JSON.stringify({ type: eventType, payload: args })
)
}首先,我們需要聲明一個類型
請看如下代碼。其中,@typedef 用于聲明一個類型,@property 用于聲明該類型包含的字段。
/**
* @typedef CallEvent
* @property {[calltype: string, telno: string, callid: string, queid: string, uudata: string]} OnAuthSuccess
* @property {[calltype: string, telno: string, callid: string, queid: string, uudata: string]} OnCalling
* @property {[calltype: string, telno: string, callid: string, queid: string, recfile: string, uudata: string]} OnCallConnect
* @property {[calltype: string]} OnCallHangup
* @property {[]} changeSeatState
* @property {[]} changeIVR
* @property {[]} changeConsult
* @property {[]} socketConnected
* @property {[telno: string, exinfo: string]} OnCustomCall
* @property {[errcode: string]} OnCallReturn
*/
然后,我們來為以上函數添加類型聲明。
請看如下代碼。其中,@template 用于聲明泛型類型,我們定義了一個泛型T,它的值取自CallEvent對象的鍵。@param 用于聲明函數參數的類型,eventType的類型為泛型T,args的類型為CallEvent[T],該類型由T的值決定。這個聲明,大家都能理解嗎?
/**
* @template {keyof CallEvent} T
* @param {T} eventType
* @param {CallEvent[T]} args
*/
const sendEventToParentWindow = (eventType, ...args) {}
現在,我們來調用以上函數試一試
當我們輸入括號后,編輯器提示我們,該函數有7種傳參方式。

當我們輸入引號后,編輯器提示出了第一個參數期望接收的值。

當我們輸入第一個參數后,編輯器給出了后面參數的提示,告訴我們還需5個參數,以及每個參數期望的類型。

當我們將changeIVR作為第一個參數時,編輯器提示我們,后面沒有需要傳的參數了。

大家說,是不是很酷?JS中很多拼寫錯誤都不會報錯,這增加了排查問題的難度。有了jsdoc,我們的拼寫錯誤將大幅減少。由于有了編輯器的智能提示,我們不需要把整個單詞都敲出來,這樣寫起來更爽了,不是嗎?