JavaScript文件里添加JSDoc注解


theme: v-green

支持的JSDoc

下面的列表列出了当前所支持的JSDoc注解,你可以用它们在JavaScript文件里添加类型信息。

注意,没有在下面列出的标记(例如@async)都是还不支持的。

  • @type
  • @param (or @arg or @argument)
  • @returns (or @return)
  • @typedef
  • @callback
  • @template
  • @class (or @constructor)
  • @this
  • @extends (or @augments)
  • @enum

它们代表的意义与usejsdoc.org上面给出的通常是一致的或者是它的超集。 下面的代码描述了它们的区别并给出了一些示例。

@type

可以使用@type标记并引用一个类型名称(原始类型,TypeScript里声明的类型,或在JSDoc里@typedef标记指定的) 可以使用任何TypeScript类型和大多数JSDoc类型。

```javascript /** * @type {string} */ var s;

/** @type {Window} */ var win;

/** @type {PromiseLike } */ var promisedString;

// You can specify an HTML Element with DOM properties /** @type {HTMLElement} */ var myElement = document.querySelector(selector); element.dataset.myData = ''; ```

@type可以指定联合类型—例如,stringboolean类型的联合。

javascript /** * @type {(string | boolean)} */ var sb;

注意,括号是可选的。

javascript /** * @type {string | boolean} */ var sb;

有多种方式来指定数组类型:

javascript /** @type {number[]} */ var ns; /** @type {Array.<number>} */ var nds; /** @type {Array<number>} */ var nas;

还可以指定对象字面量类型。 例如,一个带有a(字符串)和b(数字)属性的对象,使用下面的语法:

javascript /** @type {{ a: string, b: number }} */ var var9;

可以使用字符串和数字索引签名来指定map-likearray-like的对象,使用标准的JSDoc语法或者TypeScript语法。

``javascript /** * A map-like object that maps arbitrarystringproperties tonumber`s. * * @type {Object. } */ var stringToNumber;

/** @type {Object. } */ var arrayLike; ```

这两个类型与TypeScript里的{ [x: string]: number }{ [x: number]: any }是等同的。编译器能识别出这两种语法。

可以使用TypeScript或Closure语法指定函数类型。

javascript /** @type {function(string, boolean): number} Closure syntax */ var sbn; /** @type {(s: string, b: boolean) => number} Typescript syntax */ var sbn2;

或者直接使用未指定的Function类型:

javascript /** @type {Function} */ var fn7; /** @type {function} */ var fn6;

Closure的其它类型也可以使用:

javascript /** * @type {*} - can be 'any' type */ var star; /** * @type {?} - unknown type (same as 'any') */ var question;

转换

TypeScript借鉴了Closure里的转换语法。 在括号表达式前面使用@type标记,可以将一种类型转换成另一种类型

javascript /** * @type {number | string} */ var numberOrString = Math.random() < 0.5 ? "hello" : 100; var typeAssertedNumber = /** @type {number} */ (numberOrString)

导入类型

可以使用导入类型从其它文件中导入声明。 这个语法是TypeScript特有的,与JSDoc标准不同:

javascript /** * @param p { import("./a").Pet } */ function walk(p) { console.log(`Walking ${p.name}...`); }

导入类型也可以使用在类型别名声明中:

```javascript /** * @typedef { import("./a").Pet } Pet */

/** * @type {Pet} */ var myPet; myPet.name; ```

导入类型可以用在从模块中得到一个值的类型。

javascript /** * @type {typeof import("./a").x } */ var x = require("./a").x;

@param@returns

@param语法和@type相同,但增加了一个参数名。 使用[]可以把参数声明为可选的:

javascript // Parameters may be declared in a variety of syntactic forms /** * @param {string} p1 - A string param. * @param {string=} p2 - An optional param (Closure syntax) * @param {string} [p3] - Another optional param (JSDoc syntax). * @param {string} [p4="test"] - An optional param with a default value * @return {string} This is the result */ function stringsStringStrings(p1, p2, p3, p4){ // TODO }

函数的返回值类型也是类似的:

```javascript /** * @return {PromiseLike } */ function ps(){}

/** * @returns {{ a: string, b: number }} - May use '@returns' as well as '@return' */ function ab(){} ```

@typedef, @callback, 和 @param

@typedef可以用来声明复杂类型。 和@param类似的语法。

javascript /** * @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} */ var specialTypeObject;

可以在第一行上使用objectObject

javascript /** * @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} */ var specialTypeObject1;

@param允许使用相似的语法。 注意,嵌套的属性名必须使用参数名做为前缀:

javascript /** * @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] */ function special(options) { return (options.prop4 || 1001) + options.prop5; }

@callback@typedef相似,但它指定函数类型而不是对象类型:

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

当然,所有这些类型都可以使用TypeScript的语法@typedef在一行上声明:

javascript /** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType */ /** @typedef {(data: string, index?: number) => boolean} Predicate */

@template

使用@template声明泛型:

javascript /** * @template T * @param {T} x - A generic parameter that flows through to the return type * @return {T} */ function id(x){ return x }

用逗号或多个标记来声明多个类型参数:

javascript /** * @template T,U,V * @template W,X */

还可以在参数名前指定类型约束。 只有列表的第一项类型参数会被约束:

javascript /** * @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 */ function seriousalize(key, object) { // ???? }

@constructor

编译器通过this属性的赋值来推断构造函数,但你可以让检查更严格提示更友好,你可以添加一个@constructor标记:

```javascript /* * @constructor * @param {number} data */ function C(data) { this.size = 0; this.initialize(data); // Should error, initializer expects a string } /* * @param {string} s */ C.prototype.initialize = function (s) { this.size = s.length }

var c = new C(0); var result = C(1); // C should only be called with new ```

通过@constructorthis将在构造函数C里被检查,因此你在initialize方法里得到一个提示,如果你传入一个数字你还将得到一个错误提示。如果你直接调用C而不是构造它,也会得到一个错误。

不幸的是,这意味着那些既能构造也能直接调用的构造函数不能使用@constructor

@this

编译器通常可以通过上下文来推断出this的类型。但你可以使用@this来明确指定它的类型:

javascript /** * @this {HTMLElement} * @param {*} e */ function callbackForLater(e) { this.clientHeight = parseInt(e) // should be fine! }

@extends

当JavaScript类继承了一个基类,无处指定类型参数的类型。而@extends标记提供了这样一种方式:

javascript /** * @template T * @extends {Set<T>} */ class SortableSet extends Set { // ... }

注意@extends只作用于类。当前,无法实现构造函数继承类的情况。

@enum

@enum标记允许你创建一个对象字面量,它的成员都有确定的类型。不同于JavaScript里大多数的对象字面量,它不允许添加额外成员。

javascript /** @enum {number} */ const JSDocState = { BeginningOfLine: 0, SawAsterisk: 1, SavingComments: 2, }

注意@enum与TypeScript的@enum大不相同,它更加简单。然而,不同于TypeScript的枚举,@enum可以是任何类型:

javascript /** @enum {function(number): number} */ const Math = { add1: n => n + 1, id: n => -n, sub1: n => n - 1, }

更多示例

```javascript var someObj = { /** * @param {string} param1 - Docs on property assignments work */ x: function(param1){} };

/** * As do docs on variable assignments * @return {Window} */ let someFunc = function(){};

/** * And class methods * @param {string} greeting The greeting to use */ Foo.prototype.sayHi = (greeting) => console.log("Hi!");

/** * And arrow functions expressions * @param {number} x - A multiplier */ let myArrow = x => x * x;

/** * Which means it works for stateless function components in JSX too * @param {{a: string, b: number}} test - Some param */ var fc = (test) =>

{test.a.charAt(0)}
;

/** * A parameter can be a class constructor, using Closure syntax. * * @param {{new(...args: any[]): object}} C - The class to register */ function registerClass(C) {}

/** * @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any') */ function fn10(p1){}

/** * @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any') */ function fn9(p1) { return p1.join(); } ```

已知不支持的模式

在值空间中将对象视为类型是不可以的,除非对象创建了类型,如构造函数。

```javascript function aNormalFunction() {

} /* * @type {aNormalFunction} */ var wrong; /* * Use 'typeof' instead: * @type {typeof aNormalFunction} */ var right; ```

对象字面量属性上的=后缀不能指定这个属性是可选的:

javascript /** * @type {{ a: string, b: number= }} */ var wrong; /** * Use postfix question on the property name instead: * @type {{ a: string, b?: number }} */ var right;

Nullable类型只在启用了strictNullChecks检查时才启作用:

javascript /** * @type {?number} * With strictNullChecks: true -- number | null * With strictNullChecks: off -- number */ var nullable;

Non-nullable类型没有意义,以其原类型对待:

javascript /** * @type {!number} * Just has type number */ var normal;

不同于JSDoc类型系统,TypeScript只允许将类型标记为包不包含null。 没有明确的Non-nullable -- 如果启用了strictNullChecks,那么number是非null的。 如果没有启用,那么number是可以为null的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay·Yuen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值