以下清單概述了在 JavaScript 檔案中使用 JSDoc 註解提供類型資訊時,目前支援哪些建構。
請注意,任何未明確列在下方 (例如 @async
) 的標籤目前都不支援。
類型
類別
- 屬性修飾詞
@public
、@private
、@protected
、@readonly
@override
@extends
(或@augments
)@implements
@class
(或@constructor
)@this
文件
文件標籤在 TypeScript 和 JavaScript 中都能使用。
其他
意義通常與 jsdoc.app 中提供的標籤意義相同,或為其超集。下列程式碼說明了各標籤之間的差異,並提供每個標籤的一些範例用法。
注意:您可以使用 遊樂場來探索 JSDoc 支援。
類型
@type
您可以使用「@type」標籤來參照類型。類型可以是
- 基本類型,例如
string
或number
。 - 在 TypeScript 宣告中宣告,無論是全域或匯入。
- 在 JSDoc
@typedef
標籤中宣告。
您可以使用大多數 JSDoc 類型語法和任何 TypeScript 語法,從 最基本的類型,例如 string
到 最進階的類型,例如條件類型。
jsTry
/*** @type {string}*/vars ;/** @type {Window} */varwin ;/** @type {PromiseLike<string>} */varpromisedString ;// You can specify an HTML Element with DOM properties/** @type {HTMLElement} */varmyElement =document .querySelector (selector );element .dataset .myData = "";
@type
可以指定聯合類型 — 例如,某個項目可以是字串或布林值。
jsTry
/*** @type {string | boolean}*/varsb ;
您可以使用各種語法來指定陣列類型
jsTry
/** @type {number[]} */varns ;/** @type {Array.<number>} */varjsdoc ;/** @type {Array<number>} */varnas ;
您也可以指定物件文字類型。例如,一個具有屬性「a」(字串)和「b」(數字)的物件會使用下列語法
jsTry
/** @type {{ a: string, b: number }} */varvar9 ;
您可以使用字串和數字索引簽章來指定類似映射和陣列的物件,並使用標準 JSDoc 語法或 TypeScript 語法。
jsTry
/*** A map-like object that maps arbitrary `string` properties to `number`s.** @type {Object.<string, number>}*/varstringToNumber ;/** @type {Object.<number, object>} */vararrayLike ;
前兩個類型等同於 TypeScript 類型 { [x: string]: number }
和 { [x: number]: any }
。編譯器了解這兩種語法。
您可以使用 TypeScript 或 Google Closure 語法來指定函式類型
jsTry
/** @type {function(string, boolean): number} Closure syntax */varsbn ;/** @type {(s: string, b: boolean) => number} TypeScript syntax */varsbn2 ;
或者,您也可以只使用未指定的 Function
類型
jsTry
/** @type {Function} */varfn7 ;/** @type {function} */varfn6 ;
Closure 中的其他類型也可以使用
jsTry
/*** @type {*} - can be 'any' type*/varstar ;/*** @type {?} - unknown type (same as 'any')*/varquestion ;
轉型
TypeScript 從 Google Closure 借用 cast 語法。這讓你可以透過在任何括號表達式之前加上 @type
標籤,將類型 cast 成其他類型。
jsTry
/*** @type {number | string}*/varnumberOrString =Math .random () < 0.5 ? "hello" : 100;vartypeAssertedNumber = /** @type {number} */ (numberOrString );
你甚至可以像 TypeScript 一樣 cast 成 const
jsTry
letone = /** @type {const} */(1);
匯入類型
你可以使用匯入類型,從其他檔案匯入宣告。此語法是 TypeScript 特有的,與 JSDoc 標準不同
jsTry
// @filename: types.d.tsexport typePet = {name : string,};// @filename: main.js/*** @param {import("./types").Pet} p*/functionwalk (p ) {console .log (`Walking ${p .name }...`);}
匯入類型可以用在類型別名宣告中
jsTry
/*** @typedef {import("./types").Pet} Pet*//*** @type {Pet}*/varmyPet ;myPet .name ;
匯入類型可以用來取得模組中值的類型,如果你不知道類型,或是有個大類型,輸入起來很麻煩
jsTry
/*** @type {typeof import("./accounts").userAccount}*/varx =require ("./accounts").userAccount ;
@param
和 @returns
@param
使用與 @type
相同的類型語法,但會加上一個參數名稱。參數也可以透過將名稱用方括弧包起來,宣告為可選的
jsTry
// Parameters may be declared in a variety of syntactic forms/*** @param {string} p1 - A string param.* @param {string=} p2 - An optional param (Google Closure syntax)* @param {string} [p3] - Another optional param (JSDoc syntax).* @param {string} [p4="test"] - An optional param with a default value* @returns {string} This is the result*/functionstringsStringStrings (p1 ,p2 ,p3 ,p4 ) {// TODO}
同樣地,對於函式的回傳類型
jsTry
/*** @return {PromiseLike<string>}*/functionps () {}/*** @returns {{ a: string, b: number }} - May use '@returns' as well as '@return'*/functionab () {}
@typedef
、@callback
和 @param
你可以使用 @typedef
定義複雜類型。類似的語法適用於 @param
。
jsTry
/*** @typedef {Object} SpecialType - creates a new type named 'SpecialType'* @property {string} prop1 - a string property of SpecialType* @property {number} prop2 - a number property of SpecialType* @property {number=} prop3 - an optional number property of SpecialType* @prop {number} [prop4] - an optional number property of SpecialType* @prop {number} [prop5=42] - an optional number property of SpecialType with default*//** @type {SpecialType} */varspecialTypeObject ;specialTypeObject .prop3 ;
你可以在第一行使用 object
或 Object
。
jsTry
/*** @typedef {object} SpecialType1 - creates a new type named 'SpecialType1'* @property {string} prop1 - a string property of SpecialType1* @property {number} prop2 - a number property of SpecialType1* @property {number=} prop3 - an optional number property of SpecialType1*//** @type {SpecialType1} */varspecialTypeObject1 ;
@param
允許類似的語法,用於一次性的類型規格。請注意,巢狀屬性名稱必須加上參數名稱為前綴
jsTry
/*** @param {Object} options - The shape is the same as SpecialType above* @param {string} options.prop1* @param {number} options.prop2* @param {number=} options.prop3* @param {number} [options.prop4]* @param {number} [options.prop5=42]*/functionspecial (options ) {return (options .prop4 || 1001) +options .prop5 ;}
@callback
類似於 @typedef
,但它指定函式類型,而非物件類型
jsTry
/*** @callback Predicate* @param {string} data* @param {number} [index]* @returns {boolean}*//** @type {Predicate} */constok = (s ) => !(s .length % 2);
當然,這些類型可以使用單行 @typedef
中的 TypeScript 語法宣告
js
/** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType *//** @typedef {(data: string, index?: number) => boolean} Predicate */
@template
您可以使用 @template
標籤宣告類型參數。這讓您可以建立泛型的函式、類別或類型
jsTry
/*** @template T* @param {T} x - A generic parameter that flows through to the return type* @returns {T}*/functionid (x ) {returnx ;}consta =id ("string");constb =id (123);constc =id ({});
使用逗號或多個標籤宣告多個類型參數
js
/*** @template T,U,V* @template W,X*/
您也可以在類型參數名稱之前指定類型約束。清單中的第一個類型參數會受到約束
jsTry
/*** @template {string} K - K must be a string or string literal* @template {{ serious(): string }} Seriousalizable - must have a serious method* @param {K} key* @param {Seriousalizable} object*/functionseriousalize (key ,object ) {// ????}
最後,您可以為類型參數指定預設值
jsTry
/** @template [T=object] */classCache {/** @param {T} initial */constructor(initial ) {}}letc = newCache ()
@satisfies
@satisfies
提供存取 TypeScript 中後綴 運算子 satisfies
的功能。Satisfies 用於宣告值實作類型,但不會影響該值的類型。
jsTry
// @ts-check/*** @typedef {"hello world" | "Hello, world"} WelcomeMessage*//** @satisfies {WelcomeMessage} */constmessage = "hello world"/** @satisfies {Type '"Hello world!"' does not satisfy the expected type 'WelcomeMessage'.1360Type '"Hello world!"' does not satisfy the expected type 'WelcomeMessage'.WelcomeMessage } */constfailingMessage = "Hello world!"/** @type {WelcomeMessage} */constmessageUsingType = "hello world"
類別
類別可以宣告為 ES6 類別。
jsTry
classC {/*** @param {number} data*/constructor(data ) {// property types can be inferredthis.name = "foo";// or set explicitly/** @type {string | null} */this.title = null;// or simply annotated, if they're set elsewhere/** @type {number} */this.size ;this.initialize (data ); // Should error, initializer expects a string}/*** @param {string} s*/initialize = function (s ) {this.size =s .length ;};}varc = newC (0);// C should only be called with new, but// because it is JavaScript, this is allowed and// considered an 'any'.varresult =C (1);
它們也可以宣告為建構函式;為此,請使用 @constructor
和 @this
。
屬性修飾詞
@public
、@private
和 @protected
的作用與 TypeScript 中的 public
、private
和 protected
完全相同
jsTry
// @ts-checkclassCar {constructor() {/** @private */this.identifier = 100;}printIdentifier () {console .log (this.identifier );}}constc = newCar ();Property 'identifier' is private and only accessible within class 'Car'.2341Property 'identifier' is private and only accessible within class 'Car'.console .log (c .); identifier
@public
始終是隱含的,可以省略,但表示可以從任何地方存取屬性。@private
表示只能在包含類別中使用屬性。@protected
表示只能在包含類別中使用屬性,以及所有衍生子類別,但不能在包含類別的不同實例中使用。
@public
、@private
和 @protected
在建構函式中不起作用。
@readonly
@readonly
修飾詞可確保屬性僅在初始化期間寫入。
jsTry
// @ts-checkclassCar {constructor() {/** @readonly */this.identifier = 100;}printIdentifier () {console .log (this.identifier );}}constc = newCar ();console .log (c .identifier );
@override
@override
的作用與 TypeScript 中相同;將其用於覆寫基底類別中方法的方法
jsTry
export classC {m () { }}classD extendsC {/** @override */m () { }}
在 tsconfig 中設定 noImplicitOverride: true
以檢查覆寫。
@extends
當 JavaScript 類別延伸泛型基底類別時,JavaScript 語法中沒有傳遞型別參數。@extends
標籤允許這樣做
jsTry
/*** @template T* @extends {Set<T>}*/classSortableSet extendsSet {// ...}
請注意,@extends
僅適用於類別。目前,建構函式無法延伸類別。
@implements
同樣地,TypeScript 介面沒有 JavaScript 語法可以實作。@implements
標籤的作用與 TypeScript 中相同
jsTry
/** @implements {Print} */classTextBook {// TODO}}
@constructor
編譯器會根據 this 屬性指定推論建構函式,但如果你加入 @constructor
標籤,可以讓檢查更嚴格,建議更好
jsTry
/*** @constructor* @param {number} data*/functionC (data ) {// property types can be inferredthis.name = "foo";// or set explicitly/** @type {string | null} */this.title = null;// or simply annotated, if they're set elsewhere/** @type {number} */this.size ;this.Argument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.initialize (); data }/*** @param {string} s*/C .prototype .initialize = function (s ) {this.size =s .length ;};varc = newC (0);c .size ;varValue of type 'typeof C' is not callable. Did you mean to include 'new'?2348Value of type 'typeof C' is not callable. Did you mean to include 'new'?result =C (1);
使用 @constructor
時,this
會在建構函式 C
中檢查,因此你會取得 initialize
方法的建議,如果你傳遞數字,則會出現錯誤。如果你呼叫 C
而不是建構它,編輯器也可能會顯示警告。
遺憾的是,這表示同時也可以呼叫的建構函式無法使用 @constructor
。
@this
當編譯器有一些背景可以運作時,通常可以找出 this
的類型。當它沒有時,你可以使用 @this
明確指定 this
的類型
jsTry
/*** @this {HTMLElement}* @param {*} e*/functioncallbackForLater (e ) {this.clientHeight =parseInt (e ); // should be fine!}
文件
@deprecated
當函式、方法或屬性已棄用時,你可以透過標記 /** @deprecated */
JSDoc 註解來讓使用者知道。該資訊會顯示在完成清單中,並作為編輯器可以特別處理的建議診斷。在類似 VS Code 的編輯器中,已棄用的值通常會以刪除線樣式顯示 像這樣。
jsTry
/** @deprecated */constapiV1 = {};constapiV2 = {};apiV ;
@see
@see
讓你連結到程式中的其他名稱
tsTry
typeBox <T > = {t :T }/** @see Box for implementation details */typeBoxify <T > = { [K in keyofT ]:Box <T > };
有些編輯器會將 Box
變成連結,讓你可以輕鬆地前往並返回。
@link
@link
類似於 @see
,但它可以用於其他標籤中
tsTry
typeBox <T > = {t :T }/** @returns A {@link Box} containing the parameter. */functionbox <U >(u :U ):Box <U > {return {t :u };}
其他
@enum
@enum
標籤可讓您建立物件文字,其成員皆為指定類型。與 JavaScript 中的大多數物件文字不同,它不允許其他成員。@enum
的用意是與 Google Closure 的 @enum
標籤相容。
jsTry
/** @enum {number} */constJSDocState = {BeginningOfLine : 0,SawAsterisk : 1,SavingComments : 2,};JSDocState .SawAsterisk ;
請注意,@enum
與 TypeScript 的 enum
非常不同,而且簡單許多。但是,與 TypeScript 的列舉不同,@enum
可以有任意類型
jsTry
/** @enum {function(number): number} */constMathFuncs = {add1 : (n ) =>n + 1,id : (n ) => -n ,sub1 : (n ) =>n - 1,};MathFuncs .add1 ;
@author
您可以使用 @author
指定項目的作者
tsTry
/*** Welcome to awesome.ts* @author Ian Awesome <i.am.awesome@example.com>*/
請記得用尖括號括住電子郵件地址。否則,@example
會被解析為新標籤。
其他支援的模式
jsTry
varsomeObj = {/*** @param {string} param1 - JSDocs on property assignments work*/x : function (param1 ) {},};/*** As do jsdocs on variable assignments* @return {Window}*/letsomeFunc = function () {};/*** And class methods* @param {string} greeting The greeting to use*/Foo .prototype .sayHi = (greeting ) =>console .log ("Hi!");/*** And arrow function expressions* @param {number} x - A multiplier*/letmyArrow = (x ) =>x *x ;/*** Which means it works for function components in JSX too* @param {{a: string, b: number}} props - Some param*/varfc = (props ) => <div >{props .a .charAt (0)}</div >;/*** A parameter can be a class constructor, using Google Closure syntax.** @param {{new(...args: any[]): object}} C - The class to register*/functionregisterClass (C ) {}/*** @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any')*/functionfn10 (p1 ) {}/*** @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any')*/functionfn9 (p1 ) {returnp1 .join ();}
不支援的模式
物件文字類型中屬性類型上的後置等於號並未指定選用屬性
jsTry
/*** @type {{ a: string, b: number= }}*/varwrong ;/*** Use postfix question on the property name instead:* @type {{ a: string, b?: number }}*/varright ;
只有在 strictNullChecks
開啟時,可為空類型才有意義
jsTry
/*** @type {?number}* With strictNullChecks: true -- number | null* With strictNullChecks: false -- number*/varnullable ;
TypeScript 原生語法是聯集類型
jsTry
/*** @type {number | null}* With strictNullChecks: true -- number | null* With strictNullChecks: false -- number*/varunionNullable ;
不可為空類型沒有意義,且只會當成其原始類型處理
jsTry
/*** @type {!number}* Just has type number*/varnormal ;
與 JSDoc 的類型系統不同,TypeScript 只允許您將類型標記為包含 null 或不包含 null。沒有明確的不可為空性 — 如果 strictNullChecks 開啟,則 number
不可為空。如果關閉,則 number
可為空。
不支援的標籤
TypeScript 會忽略任何不支援的 JSDoc 標籤。
下列標籤有公開議題支援