有JSDoc還需要TypeScript嗎
這聽起來是不是很耳熟:你想寫一個小型腳本,不管是為頁面、命令行工具,還是其他什么類型。你從JavaScript開始,直到你想起寫代碼時沒有類型是多么痛苦。所以你把文件從.js重命名為.ts。然后意識到你已經打開了一個麻煩的玩意兒。
如果你在為一個網站或一個庫寫代碼,你就需要引入編譯的步驟。如果你在編寫CLI腳本,你可以求助于Deno(它支持TypeScript,開箱即用),但是你需要設置你的IDE來理解Deno的API,而且混合和匹配Deno和node并不總是那么容易。
一旦你在本地完成了所有工作,你就需要考慮如何分發你的代碼。你會檢查你編譯的.js文件嗎?你會創建一個CI管道來自動編譯你的.ts文件嗎?如果你在寫一個庫,你如何發布你的庫,以便它可以被其他項目使用?
你實際上不需要TypeScript
問題是......你不需要為了獲得靜態類型分析而編寫TypeScript!
你可以通過使用JSDoc在JavaScript中獲得TypeScript的所有好處
TypeScript所提供的是一個靜態類型系統。這意味著類型信息在運行代碼中沒有影響。當你的TypeScript被執行時,所有的類型信息都會完全丟失(這就是為什么你不寫一個類型守衛,就不能測試一個變量是否是某個類型的原因)。
這也意味著TypeScript只是提供給TypeScript分析器的額外類型信息,對運行你代碼的JavaScript引擎沒有任何意義。當你把TypeScript編譯成JavaScript時,它基本上只是從你的代碼中刪除了所有的類型信息,所以它又變成了有效的JavaScript代碼。
JSDoc
在JavaScript誕生25年多后,JSDoc作為一種注釋JavaScript代碼的方式被引入。它是一種正式的標記語言,允許IDE在開發者看到一個函數時提供額外的上下文。
類似的注釋標記存在于大多數語言中,我相信你已經知道它了。這就是它的樣子:
/**
* This is the JSDOC block. IDEs will show this text when you hover the
* printName function.
*
* @param {string} name
*/
function printName(name) {
console.log(name)
}
「TypeScript 和 JSDoc」
較少人知道的是,JSDoc是你充分使用TypeScript所需要的。TypeScript分析器能夠理解用JSDoc寫的類型,并給你提供與.ts文件相同的靜態分析。
我不會在這里提供完整的語法文檔。最重要的是你要知道,幾乎所有你能在.ts文件中做的事情,你都能用JSDoc來做。但這里有幾個例子:
帶有原生類型的函數參數:
/**
* @param {string} a
* @param {number} b
*/
function foo(a, b) {}
使用TypeScript提供的開箱即用的類型:
/**
* @param {HTMLElement} element
* @param {Window} window
*/
function foo(element, window) {}
/** @type {number[]} */
let years
定義對象字面量和函數:
/** @type {{ name: string; age: number }} */
let person
/** @type {(s: string, b: boolean) => void} */
let myCallback
從*.d.ts文件中導入類型:
/** @param {import('./types').User} user */
const deleteUser = (user) => {}
定義一個類型供以后使用:
/**
* @typedef {object} Color
* @property {number} chroma
* @property {number} hue
*/
/** @type {Color[]} */
const colors = [
{ chroma: 0.2, hue: 262 },
{ chroma: 0.2, hue: 28.3 },
]
參見官方TypeScript JSDoc文檔[1]以獲得詳盡的列表。
如果你有復雜的類型,你仍然可以編寫你的*.d.ts文件并在你的JSDoc注釋中導入它們。
注意,你仍然需要為typescript設置你的項目(和IDE),你需要創建一個tsconfig.json文件,將編譯器選項allowJs和checkJs設置為true:
// tsconfig.json
{
"compilerOptions": {
"allowJs": true,
"checkJs": true
// ...
}
}
什么時候寫TypeScript
雖然完全使用JSDoc進行類型聲明是可能的,但這并不是最方便的。TypeScript的語法要好得多,而且不那么重復。
TypeScript團隊創建了一個"作為注釋的類型"ECMAScript提案[2],允許你編寫TypeScript并在不修改的情況下在JavaScript引擎中運行(JavaScript引擎將把這些類型注釋視為注釋。)
但是在這個提案被接受之前,我們只能決定使用JSDoc或者TypeScript工具鏈。
建議
所以現在我的建議是這樣的:
- 當你正在做一個有編譯步驟的項目時,使用TypeScript沒有什么壞處
- 但是如果你不需要編譯步驟,那么堅持使用JSDoc類型注釋可能更容易。
本文譯自:https://www.pausly.app/blog/full-type-support-with-plain-javascript[3]
以上就是本文的全部內容,如果對你有所幫助,歡迎點贊、收藏、轉發~
參考資料
[1]文檔:https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
[2]ECMAScript提案:https://github.com/tc39/proposal-type-annotations
[3]https://www.pausly.app/blog/full-type-support-with-plain-javascript:https://www.pausly.app/blog/full-type-support-with-plain-javascript