使用
TypeScript
可以幫助咱們使用不少面向對象的特性和類型系統。可是從JavaScript
遷移到TypeScript
也須要巨大的時間和精力去完成重構。可是VS Code
中基於TypeScript
提供了對於JSDoc
的支持,咱們能夠利用JSDoc
來給咱們的JavaScript
代碼增長註釋,加強代碼的可讀性和可維護性。javascript
首先咱們來看一下官網上的介紹:php
JSDoc 3 is an API documentation generator for JavaScript, similar to Javadoc or phpDocumentor. You add documentation comments directly to your source code, right alongside the code itself. The JSDoc tool will scan your source code and generate an HTML documentation website for you.html
JSDoc ( JSDoc 的最新版本是JSDoc 3) 實際上是經過特定格式的註釋來幫助咱們生成 JavaScript
API文檔的工具。相似的工具還有 Javadoc
或 phpDocumentor
.java
JSDoc's purpose is to document the API of your JavaScript application or library. It is assumed that you will want to document things like modules, namespaces, classes, methods, method parameters, and so on.git
JSDoc
的提供的註釋標記類型能夠參考Block Tags, 可是到如今爲止,TypeScript
只支持了部分標記。
在語法方面,JSDoc
主要借鑑於 closure-compiler, 而 TypeScript
則有本身的一套類型語法,所以存在部分的差別。這裏只介紹在 VS Code
中基於 TypeScript
的 JSDoc
用法。github
可以在 TypeScript
中使用的類型有:web
// 定義數組類型的三種方式
/** * 定義字符串數組類型 * @type {Array<string>} */
var strArr = ['1', '2'];
// 如下是另外兩種方式,做用和第一種同樣
/** * @type {Array.<string>} */
/** * @type {string[]} */
/** * 定義boolean類型 * @type {boolean} */
var isSelected = false;
/** * 定義string類型 * @type {string} */
var name = 'xyz';
複製代碼
TypeScript
中添加的類型,好比:/** * 這是TypeScript定義的Navigator類型 * @type {Navigator} */
var navigator;
/** * 這是TypeScript定義的窗口類型 * @type {Window} */
var win;
/** * 這是TypeScript定義的HTML元素類型 * @type {HTMLElement} */
var rootElement = document.getElementById('root');
複製代碼
/** * 定義了一個Animal類型,具備名稱、年齡兩個屬性 * @type {{ name: string, age: number }} */
var cat = { name: 'miao', age: 2 };
複製代碼
// 這是一個字符串類型/布爾類型
/** * 用來描述一個多是string或boolean的類型 * @type {(string | boolean)} */
var stringOrBoolean = '';
stringOrBoolean = false;
複製代碼
/** * 用閉包的形式來定義函數類型 * @type {function(string, boolean): number} */
var function1;
/** * 用TypeScript的語法來定義函數類型 * @type {(s: string, b: boolean) => number} */
var function2;
/** * 使用內置的Function類型,不指定參數和返回值 * @type {Function} */
var function 3; 複製代碼
/** * @typedef {object} Animal - 這是自定義的Animal類型 * @property {string} name 複雜類型的一個string類型屬性 * @property {number} age 複雜類型的一個number類型屬性 * @prop {boolean} [hasOwner] 複雜類型的一個boolean類型屬性,可選 * @property {string[]=} toys 複雜類型的一個string數組屬性,可選 * @prop {string} [ownerName='xyz'] 複雜類型的一個string類型屬性,默認值爲xyz, 可選 * */
/** * @type {Animal} */
var animal = { name: 'miao', age: 2, hasOwner: false }
複製代碼
@callback相似於@typedef,區別在於: @typedef定義的是對象類型,包括函數類型,而@callback定義的是函數類型。typescript
/** * @callback Predicate * @param {string} data * @param {number} [index] * @returns {boolean} */
/** @type {Predicate} */
const ok = s => !(s.length % 2);
複製代碼
/** * @param {string} name - string類型參數 * @param {string=} age - 可選參數,number類型 * @param {number} [hasOwner] - 可選參數,number類型 * @param {string} [ownerName="xyz"] - 帶默認值的可選參數 * @return {string} 這是返回值 */
function getAnimal(name, age, hasOwner, ownerName){
// TODO
}
複製代碼
枚舉是一種在不少種語言中常見,可是在JavaScript中沒有原生支持的數據類型。可是最讓人殘念的是,enum
竟然仍是保留的關鍵字——只是一直沒有實現。 TypeScript是支持enum的,JSDoc也基於@enum提供了對枚舉的支持:數組
/** * 文件類型 * @enum * @property {string} FileType.Image 圖片 * @property {string} FileType.Video 視頻 * @property {string} FileType.Audio 音頻 * @property {string} FileType.Accessory 附件 */
export const FileType = {
/** 圖片 */
Image: '1',
/** 視頻 */
Video: '2',
/** 音頻 */
Audio: '3',
/** 附件 */
Accessory: '4'
}
複製代碼
@class/@constructor能夠用來定義構造函數,而且只容許經過 new
關鍵字來調用構造函數。閉包
/** * @constructor * @param {number} width 寬度 * @param {number} height 高度 */
function Rectangle(width, height) {
this.width = width;
this.height = height;
}
Rectangle.prototype.getArea = function() {
return this.width * this.height
}
// 必需要經過new來調用,否則編輯器會報錯
var rectrangele = new Rectangle();
複製代碼
VS Code能夠幫咱們作一些類型推斷。可是有一些場景無法很好的作出推斷,經過使用@this能夠幫助咱們來顯式指定 this
的類型。
/**
* @this {HTMLElement}
*/
function getScrollbarWidth() {
return this.offsetWidth - this.scrollWidth
}
複製代碼
JSDoc中關於@type有 Nullable Type
和 Non-nullable Type
的概念,可是在TypeScript中只容許根據 strictNullChecks
標記類型爲是否能夠爲null,並不能經過顯示標註 non-nullablity
來實現和JSDoc的一致,例如:
/** * 在JSDoc中標記爲可能爲number或null類型 * @type {?number} */
/** * 在JSDoc中標記爲number類型,而且不可能爲null類型 * @type {!number} */
/** * 以上兩種寫法,在TypeScript下都等價於以下 * @type {number} */
複製代碼
這是在TypeScript中獨有的,JSDoc並不支持
// a.js
/** * @typedef Pet * @property name {string} */
/** * @type {Pet} */
var cat = { name: 'a' };
module.exports = {
// cat
};
// b.js
/** * @param p {import('./a').Pet} */
function walk(p) {
console.log(`${p.name} is walking!`)
}
// 也能夠給引入的類型起別名
/** * @typedef { import('./a').Pet } MyPet */
/** * @type {MyPet} */
var mimi = { name: 'mimi' }
複製代碼
這是JSDoc文檔中沒有說起的一種定義類型,只在google closure compiler中有說起,可是VS Code中有對應的支持:
/** * @param {T} x * @param {S} y * @template {number|string} T * @template {number|string} S */
function foo(x,y) { x=y; }
複製代碼
這幾項用的都很少,咱們能夠看看官方文檔的一些示例:
/** * @template T * @extends {Set<T>} */
class SortableSet extends Set {
// ...
}
複製代碼
須要注意的是@extends/@augments只能用來定義基類的泛型參數,不能用來描述類的繼承關係:
class Animal() {
run() {
}
}
/** * @extends {Animal} */
class Cat { }
var cat = new Cat()
// 這裏會沒有代碼提示
cat.run()
複製代碼