我們知道 TypeScript 2.3 以后的版本支持使用--checkJs
對.js
文件進行類型檢查和錯誤提示。 但是由於 JavaScript 是弱類型語言,在編寫代碼的時候,是無法檢測變量的類型的。
因此每次運行代碼類型報錯的時候,我心中都會冒出來一個強烈的願望:要是 JavaScript是強類型的多好!
好消息是,JSDoc 的 @ts-check
,可以現實這個願望。
立即上手
如果能有機會使用 TypeScript 那當然是最好,但是往往開發的老項目在早期都是 JavaScript 完成的,如果都遷移到 TypeScript 版本工作量是龐大的,而且不可避免出現許多bug問題,那么有沒有一種方式可以無痛的在使用JavaScript的同時享受到TypeScript的類型檢查呢?
答案就是 // @ts-check
,在 js 文件的頭部引入這樣一行注釋,然后配合JSDoc
就可以在JavaScript代碼中使用 TypeScript的類型檢查了。
舉個例子,在下圖中我們首先聲明了一個變量 a,然后把數字 1 賦給了它,接着又把字符串 '1' 賦給了它,看起來好像沒有什么問題,而且運行起來也不會報錯。
let a = 1;
a = 'a';
然后我們加上 // @ts-check
試試:
// @ts-check
/**
* @type {Number}
*/
let a = 1;
a = '1';
神奇的一幕出現了,在變量a賦值的下面,出現了紅色波浪線,鼠標放上去提示:
let a: number
@type — {Number}
不能將類型“"1"”分配給類型“number”。ts(2322)
也就是說我們將一個字符串賦值給了一個數字類型的變量是有問題的,這個時候我們未運行程序,但是編輯器已經幫我們分析出了代碼可能存在的問題,這時候我們運行代碼,是沒有報錯的。
因為這個類型檢測只是讓我們按照TypeScript的強類型語言檢測類型問題,但是我們依然是JavaScript代碼依然會按照JavaScript的代碼邏輯運行,如是TypeScript代碼的話,這里運行就會報錯。
JSDoc 類型標記
既然ts-check這么好用,我們來看看 JSDoc 類型的注釋支持哪些類型的檢測。
根據官方文檔,JSDoc現在支持下面幾個類型檢測:
@type
@param
(or@arg
or@argument
)@returns
(or@return
)@typedef
@callback
@template
@class
(or@constructor
)@this
@extends
(or@augments
)@enum
下面我們選擇常用的標記進行說明,更多更詳細的標記可以參考官方文檔。
@type
描述:用來聲明變量的類型。
/**
* - string類型
* @type {string}
*/
let a1;
/**
* - windows對象類型
* @type {Window}
*/
let a2;
/**
* - string或者boolean類型
* @type {string | boolean}
*/
let sb;
// -------- 多種方式指定數組類型--------
/** @type {number[]} */
var ns;
/** @type {Array.<number>} */
var nds;
/** @type {Array<number>} */
var nas;
// ---- 還可以指定對象字面量類型。 例如,一個帶有a(字符串)和b(數字)屬性的對象---
/** @type {{ a: string, b: number }} */
var var9;
@param和@returns
描述:@param
語法和@type
相同,但增加了一個參數名。
/**
* 聲明函數參數類型
* @param {string} p1 - p1 是 string 類型參數
* @param {string=} p2 - p2 是可選的 string 類型參數
* @param {string} [p3] - 另外一種可選參數寫法
* @param {string} [p4="test"] - p4 是可選的 string 類型參數(默認值為 "test")
* @return {string} - 函數返回值是 string 類型
*/
function fn3(p1, p2, p3, p4){
// TODO
}
/**
* 用 “return” 說明函數的返回值類型
* @return {number}
*/
function fn1() {}
/**
* 可以像使用 "@return" 一樣使用 "@returns"
* @returns {{a: string, b: number}}
*/
function fn2() {}
@typedef
描述:@typedef
可以用來聲明復雜類型,和@param
類似的語法。
/**
* 用 "@typedef" 自定義復雜類型
* @typedef {Object} SpecialType - 創建一個新的類型 'SpecialType'
* @property {string} prop1 - SpecialType 屬性 prop1 是 string 類型
* @property {number} prop2 - SpecialType 屬性 prop2 是 number 類型
* @property {number=} prop3 - SpecialType 屬性 prop3 是可選的 number 類型
* @prop {number} [prop4] - SpecialType 屬性 prop4 是可選的 number 類型
* @prop {number} [prop5=42] - SpecialType 屬性 prop5 是可選的 number 類型(默認值 42))
*/
/** @type {SpecialType} */
let specialTypeObject;
可以在第一行上使用
object
或Object
。
實驗要求
經測試,在 VSCode
和 IDEA
下可以直接使用ts-check
的類型檢測,sublime
等編輯器不可以,應該是要下載對應的插件才可以。
寫在最后
對於老項目,使用 // @ts-check
和 JSDoc
來來享受TypeScript類型系統的好處是最簡單、學習成本最低的方法。
而對於新項目,則更加推薦直接使用 TypeScript 來進行代碼編寫,並且各大框架里面都是用的TypeScript進行的代碼編寫,在可期的未來,TypeScript將會越來越受歡迎。