整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ
沒辦法用 TypeScript?別擔心,你還可以寫 JSDoc 標注類型

前言
如果你的公司專案沒辦法使用 TypeScript 的話,但又希望可以有類似 TypeScript 的類型檢查,那麼你可以試試看 JSDoc 來標注類型,這樣就可以有類似 TypeScript 的類型檢查了。
JSDoc 是什麼?
首先先聊一下 JSDoc 是什麼東西,JSDoc 全名是「JavaScript Documentation」,中文翻譯是「JavaScript 文件」,它是一個專門用來標註 JavaScript 文件的工具。
那它可以做什麼呢?其實它可以幫助你標註類型,例如:型別、參數與回傳值等等,因此在還沒有 TypeScript 之前,JSDoc 會是一個非常好用的工具,因為已經足夠堪用了。
那麼接下來我們就準備來看看 JSDoc 該怎麼使用吧!但是在開始之前我想先說明一下我的 IDE,也就是 Visual Studio Code,身為地表上最強大最好用的 IDE,它對於 JSDoc 的支援也是非常的好,因此我會以 Visual Studio Code 來做為示範。
Note
JSDoc 其實很早就出現了,約 1999 年左右,所以其實比 TypeScript 還要早出來唷。
準備動作
首先我們先使用 VSCode 建立一個專案叫做 jsdoc-demo,並且請在該專案初始化 npm
1 | |
接著建立一個 index.js 檔案,所以你目前的專案結構應該會長這樣

準備好差不多之後,我們就繼續往下吧。
JSDoc 的撰寫方式
JSDoc 的撰寫方式並不困難,首先我這邊先寫一段範例程式碼
1 | |
接下來該怎麼撰寫呢?你只需要在該函式的上方加上 /**,我們強大的 VSCode 就會提示你 JSDoc 註解

此時你只需要按下 Enter 鍵,就會自動幫你產生 JSDoc 註解了,如下圖

是不是超級方便呢?那麼這邊我們可以看到 VSCode 自動幫我們產生了 @param {*} name 與 @returns,那這邊我們該怎麼撰寫呢?其實很簡單,通常我們會去描述該函式的功能、參數的型別以及回傳值的型別,所以會這樣子撰寫
1 | |
接下來當你滑鼠只要移動過去 sayHi 這個函式,就會出現提示訊息

因此當如果你在其他地方使用到該函式的時候,就可以透過 JSDoc 來提示你該函式的功能、參數的型別以及回傳值的型別,大大減少你還要去看函式是幹嘛的、該傳什麼參數以及回傳什麼值的時間。
當然 JSDoc 不只有這樣,你也可以使用 @example 來描述該函式的使用方式
1 | |

那麼如果是可以接受多個型別呢?例如:string 或是 number,那麼你可以這樣寫
1 | |

那麼這邊也來提一件事情,為什麼會說如果不能使用 TypeScript 的話,JSDoc 也是一個不錯的選擇呢?透過上面示範我們可以知道 JSDoc 確實是可以幫助到我們一些問題,但是這樣子遠遠是不夠的,因為開發者是人,所以可能 sayHi 我們就已經寫了 @param { string } name 名字,但是我們還是不小心在呼叫 sayHi 的時候傳入了 number
1 | |
那這樣子就會造成錯誤,對於我們開發者來講,是有可能發生一些 Bug 的,所以就只能認命使用 TypeScript 嗎?不,其實 JSDoc 也可以做到型別驗證的,只是目前我們的環境還沒有設定好,所以我們先來設定一下。
JSDoc 類型檢查和自動完成
首先我們在專案根目錄建立一個 jsconfig.json 檔案,並且輸入以下內容
1 | |
接著你應該就可以看到錯誤提示訊息囉

而且如果你沒有正確傳入參數的話,也會有提示訊息

如果你是 TypeScript 的開發者應該會覺得 jsconfig.json 很熟悉,因為 jsconfig.js 是由 tsconfig.js 所衍生出來的,所以你可以在 jsconfig.js 中使用 tsconfig.js 的設定,例如:"target": "es6"、"module": "commonjs" 等等,這邊我們就不多做介紹,如果你想要了解更多,可以參考官方文件。
JSDoc 其他寫法
講完了前面 JSDoc 的基本寫法跟基本設置後,我們繼續來聊一下 JSDoc 的其他寫法,以實戰開發來講,我們不可能這麼單純,畢竟還會有陣列跟物件等狀況,所以一開始我們先以一個單純的變數宣告來講,如果要替變數宣告上型別的話,那就會使用到新的 JSDoc 語法,也就是 @type,底下我也列出一些示範寫法
變數宣告
1 | |

透過定義變數其實也可以像 TypeScript 讓下拉選取變得很正確

單型別陣列
1 | |

多型別陣列
1 | |

物件
1 | |

如果你先寫 JSDoc 再去寫物件屬性時,當你屬性沒有對上 JSDoc 也會出現警告

函式
1 | |
上面是我們前面所示範的函式,但是我們實戰開發上是很長傳入物件的,所以我們來看一下物件的寫法
1 | |

當然也是一樣可以驗證的

如果是函式的話呢?其實也很簡單
1 | |

如果函式沒打算回傳值的話,那就可以使用 void 來定義
1 | |
JSDoc 進階寫法 - @typedef
當我們型別比較複雜時,我們是可以使用 @typedef 來定義型別的,這樣就不用一直重複寫了,例如:我們要定義一個物件型別,裡面有 name 跟 age 兩個屬性,這時候我們就可以使用 @typedef 來定義
1 | |
通常 @typedef 會放在檔案的最上面,因此就會像這樣
1 | |
同樣的,如果你傳入錯誤的型別,也會出現警告

那麼如果我們定義的 @typedef 需要跨檔案使用時,我們可以使用 @typedef 的 @global 來定義,這樣就可以跨檔案使用了
1 | |
接下來你就可以在其他檔案使用了
1 | |
通常會把 @typedef 定義在 types.js 檔案中,所以會建立一個資料夾叫做 types,然後在裡面建立 index.js 檔案,內容如下
1 | |
JSDoc 常見語法總結
最後就差不多要來準備下個結論,也就是上面文章中有使用到的 JSDoc 語法
@param:函式參數@returns:函式回傳值@example:使用範例@typedef:自定義型別@global:跨檔案使用@typedef@property:物件屬性@type:型別
當然不只有這些,所以如果你想要更深入了解的話,我會建議你直接看 JSDoc 官方文件,因為 JSDoc 語法真的非常多,不太可能每一個都介紹到,所以我只介紹了常用的,如果你想要更深入了解的話,可以直接看官方文件哩~
結論
其實我們可以發現就算沒有使用 TypeScript,也可以達到類似 TypeScript 的型別驗證,最後這邊我也將上面範例檔案整理了一下,以便你可以搭配這一篇文章來看
基本上裡面我都有寫一些範例了,應該是可以讓你更了解 JSDoc 的使用方式哩
整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ