下面的列表概述了在使用 JSDoc 注释在 JavaScript 文件中提供类型信息时当前支持哪些结构。
¥The list below outlines which constructs are currently supported when using JSDoc annotations to provide type information in JavaScript files.
请注意,尚不支持以下未明确列出的任何标签(例如 @async
)。
¥Note any tags which are not explicitly listed below (such as @async
) are not yet supported.
类型
¥Types
类
¥Classes
-
属性修饰符
@public
,@private
,@protected
,@readonly
¥Property Modifiers
@public
,@private
,@protected
,@readonly
-
¥
@class
(or@constructor
)
文档
¥Documentation
文档标签适用于 TypeScript 和 JavaScript。
¥Documentation tags work in both TypeScript and JavaScript.
其他
¥Other
含义通常与 jsdoc.app 处给出的标签的含义相同或超集。下面的代码描述了差异并给出了每个标签的一些示例用法。
¥The meaning is usually the same, or a superset, of the meaning of the tag given at jsdoc.app. The code below describes the differences and gives some example usage of each tag.
注意:你可以使用 探索 JSDoc 支持的在线运行。
¥Note: You can use the playground to explore JSDoc support.
类型
¥Types
@type
你可以使用 “@type” 标记引用类型。类型可以是:
¥You can reference types with the “@type” tag. The type can be:
-
基础类型,如
string
或number
。¥Primitive, like
string
ornumber
. -
在 TypeScript 声明中声明,全局或导入。
¥Declared in a TypeScript declaration, either global or imported.
-
在 JSDoc
@typedef
标签中声明。¥Declared in a JSDoc
@typedef
tag.
你可以使用大多数 JSDoc 类型语法和任何 TypeScript 语法,从 最基本的像 string
到 最高级的,比如条件类型。
¥You can use most JSDoc type syntax and any TypeScript syntax, from the most basic like string
to the most advanced, like conditional types.
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
可以指定联合类型 - 例如,某些内容可以是字符串或布尔值。
¥@type
can specify a union type — for example, something can be either a string or a boolean.
jsTry
/*** @type {string | boolean}*/varsb ;
你可以使用多种语法指定数组类型:
¥You can specify array types using a variety of syntaxes:
jsTry
/** @type {number[]} */varns ;/** @type {Array.<number>} */varjsdoc ;/** @type {Array<number>} */varnas ;
你还可以指定对象字面类型。例如,具有属性 ‘a’(字符串)和 ‘b’(数字)的对象使用以下语法:
¥You can also specify object literal types. For example, an object with properties ‘a’ (string) and ‘b’ (number) uses the following syntax:
jsTry
/** @type {{ a: string, b: number }} */varvar9 ;
你可以使用标准 JSDoc 语法或 TypeScript 语法,使用字符串和数字索引签名来指定类映射和类数组对象。
¥You can specify map-like and array-like objects using string and number index signatures, using either standard JSDoc syntax or TypeScript syntax.
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 }
。编译器理解这两种语法。
¥The preceding two types are equivalent to the TypeScript types { [x: string]: number }
and { [x: number]: any }
. The compiler understands both syntaxes.
你可以使用 TypeScript 或 Google Closure 语法指定函数类型:
¥You can specify function types using either TypeScript or Google Closure syntax:
jsTry
/** @type {function(string, boolean): number} Closure syntax */varsbn ;/** @type {(s: string, b: boolean) => number} TypeScript syntax */varsbn2 ;
或者你可以只使用未指定的 Function
类型:
¥Or you can just use the unspecified Function
type:
jsTry
/** @type {Function} */varfn7 ;/** @type {function} */varfn6 ;
Closure 的其他类型也可以工作:
¥Other types from Closure also work:
jsTry
/*** @type {*} - can be 'any' type*/varstar ;/*** @type {?} - unknown type (same as 'any')*/varquestion ;
Casts
TypeScript 借鉴了 Google Closure 的强制转换语法。这使你可以通过在任何带括号的表达式之前添加 @type
标记来将类型转换为其他类型。
¥TypeScript borrows cast syntax from Google Closure.
This lets you cast types to other types by adding a @type
tag before any parenthesized expression.
jsTry
/*** @type {number | string}*/varnumberOrString =Math .random () < 0.5 ? "hello" : 100;vartypeAssertedNumber = /** @type {number} */ (numberOrString );
你甚至可以像 TypeScript 一样转换为 const
:
¥You can even cast to const
just like TypeScript:
jsTry
letone = /** @type {const} */(1);
导入类型
¥Import types
你可以使用导入类型从其他文件导入声明。此语法特定于 TypeScript,与 JSDoc 标准不同:
¥You can import declarations from other files using import types. This syntax is TypeScript-specific and differs from the JSDoc standard:
jsTry
// @filename: types.d.tsexport typePet = {name : string,};// @filename: main.js/*** @param {import("./types").Pet} p*/functionwalk (p ) {console .log (`Walking ${p .name }...`);}
导入类型可以在类型别名声明中使用:
¥import types can be used in type alias declarations:
jsTry
/*** @typedef {import("./types").Pet} Pet*//*** @type {Pet}*/varmyPet ;myPet .name ;
import types 可以用来从模块中获取值的类型,如果你不知道类型,或者如果它有一个大的类型,输入起来很烦人:
¥import types can be used to get the type of a value from a module if you don’t know the type, or if it has a large type that is annoying to type:
jsTry
/*** @type {typeof import("./accounts").userAccount}*/varx =require ("./accounts").userAccount ;
@param
和 @returns
¥@param
and @returns
@param
使用与 @type
相同的类型语法,但添加了参数名称。该参数也可以通过用方括号括起名称来声明为可选:
¥@param
uses the same type syntax as @type
, but adds a parameter name.
The parameter may also be declared optional by surrounding the name with square brackets:
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}
同样,对于函数的返回类型:
¥Likewise, for the return type of a function:
jsTry
/*** @return {PromiseLike<string>}*/functionps () {}/*** @returns {{ a: string, b: number }} - May use '@returns' as well as '@return'*/functionab () {}
@typedef
、@callback
和 @param
¥@typedef
, @callback
, and @param
你可以使用 @typedef
定义复杂类型。类似的语法适用于 @param
。
¥You can define complex types with @typedef
.
Similar syntax works with @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
。
¥You can use either object
or Object
on the first line.
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
允许对一次性类型规范使用类似的语法。请注意,嵌套的属性名称必须以参数名称为前缀:
¥@param
allows a similar syntax for one-off type specifications.
Note that the nested property names must be prefixed with the name of the parameter:
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
类似,但它指定的是函数类型而不是对象类型:
¥@callback
is similar to @typedef
, but it specifies a function type instead of an object type:
jsTry
/*** @callback Predicate* @param {string} data* @param {number} [index]* @returns {boolean}*//** @type {Predicate} */constok = (s ) => !(s .length % 2);
当然,这些类型中的任何一种都可以在单行 @typedef
中使用 TypeScript 语法声明:
¥Of course, any of these types can be declared using TypeScript syntax in a single-line @typedef
:
js
/** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType *//** @typedef {(data: string, index?: number) => boolean} Predicate */
@template
你可以使用 @template
标记声明类型参数。这使你可以创建泛型的函数、类或类型:
¥You can declare type parameters with the @template
tag.
This lets you make functions, classes, or types that are generic:
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 ({});
使用逗号或多个标签来声明多个类型参数:
¥Use comma or multiple tags to declare multiple type parameters:
js
/*** @template T,U,V* @template W,X*/
你还可以在类型参数名称之前指定类型约束。只有列表中的第一个类型参数受到约束:
¥You can also specify a type constraint before the type parameter name. Only the first type parameter in a list is constrained:
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 ) {// ????}
最后,你可以为类型参数指定默认值:
¥Finally, you can specify a default for a type parameter:
jsTry
/** @template [T=object] */classCache {/** @param {T} initial */constructor(initial ) {}}letc = newCache ()
@satisfies
@satisfies
提供对 TypeScript 中后缀 运算符 satisfies
的访问。Satisfies 用于声明某个值实现了某种类型,但不影响该值的类型。
¥@satisfies
provides access to the postfix operator satisfies
in TypeScript. Satisfies is used to declare that a value implements a type but does not affect the type of the value.
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"
类
¥Classes
类可以声明为 ES6 类。
¥Classes can be declared as ES6 classes.
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
。
¥They can also be declared as constructor functions; use @constructor
along with @this
for this.
属性修饰符
¥Property Modifiers
@public
、@private
和 @protected
在 TypeScript 中的工作方式与 public
、private
和 protected
完全相同:
¥@public
, @private
, and @protected
work exactly like public
, private
, and protected
in TypeScript:
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
总是隐含的,可以省略,但表示可以从任何地方访问属性。¥
@public
is always implied and can be left off, but means that a property can be reached from anywhere. -
@private
表示属性只能在包含类中使用。¥
@private
means that a property can only be used within the containing class. -
@protected
表示属性只能在包含类和所有派生子类中使用,但不能在包含类的不同实例上使用。¥
@protected
means that a property can only be used within the containing class, and all derived subclasses, but not on dissimilar instances of the containing class.
@public
、@private
和 @protected
在构造函数中不起作用。
¥@public
, @private
, and @protected
do not work in constructor functions.
@readonly
@readonly
修饰符确保只在初始化期间写入属性。
¥The @readonly
modifier ensures that a property is only ever written to during initialization.
jsTry
// @ts-checkclassCar {constructor() {/** @readonly */this.identifier = 100;}printIdentifier () {console .log (this.identifier );}}constc = newCar ();console .log (c .identifier );
@override
@override
的工作方式与 TypeScript 相同;在覆盖基类方法的方法上使用它:
¥@override
works the same way as in TypeScript; use it on methods that override a method from a base class:
jsTry
export classC {m () { }}classD extendsC {/** @override */m () { }}
在 tsconfig 中设置 noImplicitOverride: true
以检查覆盖。
¥Set noImplicitOverride: true
in tsconfig to check overrides.
@extends
当 JavaScript 类扩展泛型基类时,没有用于传递类型参数的 JavaScript 语法。@extends
标签允许这样:
¥When JavaScript classes extend a generic base class, there is no JavaScript syntax for passing a type argument. The @extends
tag allows this:
jsTry
/*** @template T* @extends {Set<T>}*/classSortableSet extendsSet {// ...}
请注意,@extends
仅适用于类。目前,构造函数无法扩展类。
¥Note that @extends
only works with classes. Currently, there is no way for a constructor function to extend a class.
@implements
同样,没有用于实现 TypeScript 接口的 JavaScript 语法。@implements
标签就像在 TypeScript 中一样工作:
¥In the same way, there is no JavaScript syntax for implementing a TypeScript interface. The @implements
tag works just like in TypeScript:
jsTry
/** @implements {Print} */classTextBook {// TODO}}
@constructor
编译器根据 this-property 赋值推断构造函数,但如果添加 @constructor
标记,则可以使检查更严格并提供更好的建议:
¥The compiler infers constructor functions based on this-property assignments, but you can make checking stricter and suggestions better if you add a @constructor
tag:
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);
注意:错误消息仅显示在启用了 一个 JSConfig 和
checkJs
的 JS 代码库中。¥Note: Error messages only show up in JS codebases with a JSConfig and
checkJs
enabled.
对于 @constructor
,this
在构造函数 C
中进行检查,因此你将获得 initialize
方法的建议,如果你向它传递一个数字,则会出现错误。如果你调用 C
而不是构造它,你的编辑器也可能会显示警告。
¥With @constructor
, this
is checked inside the constructor function C
, so you will get suggestions for the initialize
method and an error if you pass it a number. Your editor may also show warnings if you call C
instead of constructing it.
不幸的是,这意味着同样可调用的构造函数不能使用 @constructor
。
¥Unfortunately, this means that constructor functions that are also callable cannot use @constructor
.
@this
当编译器有一些上下文可以使用时,它通常可以找出 this
的类型。如果没有,你可以使用 @this
显式指定 this
的类型:
¥The compiler can usually figure out the type of this
when it has some context to work with. When it doesn’t, you can explicitly specify the type of this
with @this
:
jsTry
/*** @this {HTMLElement}* @param {*} e*/functioncallbackForLater (e ) {this.clientHeight =parseInt (e ); // should be fine!}
文档
¥Documentation
@deprecated
当一个函数、方法或属性被弃用时,你可以通过用 /** @deprecated */
JSDoc 注释标记它来让用户知道。该信息显示在完成列表中,并作为编辑可以专门处理的建议诊断。在 VS Code 等编辑器中,不推荐使用的值通常以删除线样式 like this 显示。
¥When a function, method, or property is deprecated you can let users know by marking it with a /** @deprecated */
JSDoc comment. That information is surfaced in completion lists and as a suggestion diagnostic that editors can handle specially. In an editor like VS Code, deprecated values are typically displayed in a strike-through style like this.
jsTry
/** @deprecated */constapiV1 = {};constapiV2 = {};apiV ;
@see
@see
允许你链接到程序中的其他名称:
¥@see
lets you link to other names in your program:
tsTry
typeBox <T > = {t :T }/** @see Box for implementation details */typeBoxify <T > = { [K in keyofT ]:Box <T > };
一些编辑器会将 Box
变成一个链接,以便于跳转和返回。
¥Some editors will turn Box
into a link to make it easy to jump there and back.
@link
@link
与 @see
类似,只是它可以在其他标签内使用:
¥@link
is like @see
, except that it can be used inside other tags:
tsTry
typeBox <T > = {t :T }/** @returns A {@link Box} containing the parameter. */functionbox <U >(u :U ):Box <U > {return {t :u };}
其他
¥Other
@enum
@enum
标记允许你创建一个对象字面,其成员都是指定类型。与 JavaScript 中的大多数对象字面不同,它不允许其他成员。@enum
旨在与 Google Closure 的 @enum
标签兼容。
¥The @enum
tag allows you to create an object literal whose members are all of a specified type. Unlike most object literals in JavaScript, it does not allow other members.
@enum
is intended for compatibility with Google Closure’s @enum
tag.
jsTry
/** @enum {number} */constJSDocState = {BeginningOfLine : 0,SawAsterisk : 1,SavingComments : 2,};JSDocState .SawAsterisk ;
请注意,@enum
与 TypeScript 的 enum
截然不同,而且简单得多。然而,与 TypeScript 的枚举不同,@enum
可以是任何类型:
¥Note that @enum
is quite different from, and much simpler than, TypeScript’s enum
. However, unlike TypeScript’s enums, @enum
can have any type:
jsTry
/** @enum {function(number): number} */constMathFuncs = {add1 : (n ) =>n + 1,id : (n ) => -n ,sub1 : (n ) =>n - 1,};MathFuncs .add1 ;
@author
你可以使用 @author
指定项目的作者:
¥You can specify the author of an item with @author
:
tsTry
/*** Welcome to awesome.ts* @author Ian Awesome <i.am.awesome@example.com>*/
请记住用尖括号将电邮地址括起来。否则,@example
将被解析为新标签。
¥Remember to surround the email address with angle brackets.
Otherwise, @example
will be parsed as a new tag.
其他支持的模式
¥Other supported patterns
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 ();}
不支持的模式
¥Unsupported patterns
对象字面类型中属性类型的后缀等于未指定可选属性:
¥Postfix equals on a property type in an object literal type doesn’t specify an optional property:
jsTry
/*** @type {{ a: string, b: number= }}*/varwrong ;/*** Use postfix question on the property name instead:* @type {{ a: string, b?: number }}*/varright ;
可空类型只有在 strictNullChecks
打开时才有意义:
¥Nullable types only have meaning if strictNullChecks
is on:
jsTry
/*** @type {?number}* With strictNullChecks: true -- number | null* With strictNullChecks: false -- number*/varnullable ;
TypeScript 原生语法是联合类型:
¥The TypeScript-native syntax is a union type:
jsTry
/*** @type {number | null}* With strictNullChecks: true -- number | null* With strictNullChecks: false -- number*/varunionNullable ;
不可为 null 的类型没有意义,并被视为它们的基础类型:
¥Non-nullable types have no meaning and are treated just as their original type:
jsTry
/*** @type {!number}* Just has type number*/varnormal ;
与 JSDoc 的类型系统不同,TypeScript 只允许你将类型标记为包含或不包含 null。没有明确的不可空性 - 如果启用了 strictNullChecks,则 number
不可空。如果关闭,则 number
可为空。
¥Unlike JSDoc’s type system, TypeScript only allows you to mark types as containing null or not.
There is no explicit non-nullability — if strictNullChecks is on, then number
is not nullable.
If it is off, then number
is nullable.
不支持的标签
¥Unsupported tags
TypeScript 会忽略任何不受支持的 JSDoc 标签。
¥TypeScript ignores any unsupported JSDoc tags.
以下标签有未解决的问题来支持它们:
¥The following tags have open issues to support them:
-
@const
(问题 #19672)¥
@const
(issue #19672) -
@inheritdoc
(问题 #23215)¥
@inheritdoc
(issue #23215) -
@memberof
(问题 #7237)¥
@memberof
(issue #7237) -
@yields
(问题 #23857)¥
@yields
(issue #23857)