基於TypeScript的JSDoc註釋

使用 TypeScript 可以幫助咱們使用不少面向對象的特性和類型系統。可是從 JavaScript 遷移到 TypeScript 也須要巨大的時間和精力去完成重構。可是 VS Code 中基於 TypeScript提供了對於 JSDoc 的支持,咱們能夠利用 JSDoc 來給咱們的 JavaScript代碼增長註釋,加強代碼的可讀性和可維護性。javascript

什麼是JSDoc?

首先咱們來看一下官網上的介紹: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文檔的工具。相似的工具還有 JavadocphpDocumentor.java

JSDoc能夠作哪些註釋?

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 中基於 TypeScriptJSDoc 用法github

定義對象類型——@type

可以在 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');

複製代碼
  • 大部分的JSDoc類型
  1. 對象類型:
/** * 定義了一個Animal類型,具備名稱、年齡兩個屬性 * @type {{ name: string, age: number }} */
var cat = { name: 'miao', age: 2 };
複製代碼
  1. 聯合類型:適合於可能擁有多種類型之一的數據類型,該類型能夠從提供的類型列表中肯定
// 這是一個字符串類型/布爾類型
/** * 用來描述一個多是string或boolean的類型 * @type {(string | boolean)} */
var stringOrBoolean = '';
stringOrBoolean = false;
複製代碼
  1. 定義函數類型
/** * 用閉包的形式來定義函數類型 * @type {function(string, boolean): number} */
var function1;

/** * 用TypeScript的語法來定義函數類型 * @type {(s: string, b: boolean) => number} */
var function2;

/** * 使用內置的Function類型,不指定參數和返回值 * @type {Function} */
var function 3; 複製代碼

定義自定義類型和屬性——@typedef和@property/@prop

  • 若是要建立一些在JSDoc中使用的複雜類型,就須要用@typedef去定義了這個類型
  • 而後使用@property或@prop去定義類型的屬性。
  • 定義完成後,經過@type去使用自行定義的類型:
/** * @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

@callback相似於@typedef,區別在於: @typedef定義的是對象類型,包括函數類型,而@callback定義的是函數類型typescript

/** * @callback Predicate * @param {string} data * @param {number} [index] * @returns {boolean} */
/** @type {Predicate} */
const ok = s => !(s.length % 2);
複製代碼

定義函數參數和返回值——@param/@arg/@arguments和@return

  • @param/@arg/@arguments用來定義函數參數,使用了和@type相同的類型語法
  • @return用來定義函數的返回值。關於參數的定義方式和@typedef類似。
/** * @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
}
複製代碼

定義枚舉——@enum

枚舉是一種在不少種語言中常見,可是在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

@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();

複製代碼

定義this指向——@this

VS Code能夠幫咱們作一些類型推斷。可是有一些場景無法很好的作出推斷,經過使用@this能夠幫助咱們來顯式指定 this 的類型。

/**
 * @this {HTMLElement}
 */
function getScrollbarWidth() {
  return this.offsetWidth - this.scrollWidth
}
複製代碼

其餘

@type——關於Nullable和Non-nullable

JSDoc中關於@type有 Nullable TypeNon-nullable Type 的概念,可是在TypeScript中只容許根據 strictNullChecks 標記類型爲是否能夠爲null,並不能經過顯示標註 non-nullablity 來實現和JSDoc的一致,例如:

/** * 在JSDoc中標記爲可能爲number或null類型 * @type {?number} */

/** * 在JSDoc中標記爲number類型,而且不可能爲null類型 * @type {!number} */

 /** * 以上兩種寫法,在TypeScript下都等價於以下 * @type {number} */
複製代碼

在TypeScript中導入其餘文件中的定義

這是在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' }
複製代碼

定義泛型——@template

這是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; }
複製代碼

定義擴展泛型基類——@extends/@augments

這幾項用的都很少,咱們能夠看看官方文檔的一些示例:

/** * @template T * @extends {Set<T>} */
class SortableSet extends Set {
  // ...
}
複製代碼

須要注意的是@extends/@augments只能用來定義基類的泛型參數,不能用來描述類的繼承關係

class Animal() {
  run() {

  }
}

/** * @extends {Animal} */
class Cat { }

var cat = new Cat()
// 這裏會沒有代碼提示
cat.run()
複製代碼

參考資料

相關文章
相關標籤/搜索