JSDoc Справочник
Ниже приведён список конструкций, которые в настоящее время поддерживаются при использовании аннотаций JSDoc для предоставления информации о типах в файлах JavaScript.
Обратите внимание, что любые теги, которые явно не указаны ниже (например, @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, до наиболее продвинутого, как условные типы.
/**
* @type {string}
*/
var s;
/** @type {Window} */
var win;
/** @type {PromiseLike<string>} */
var promisedString;
// You can specify an HTML Element with DOM properties
/** @type {HTMLElement} */
var myElement = document.querySelector(selector);
element.dataset.myData = ""; @type может указать объединение типов — например, что-то может быть либо строкой, либо булевым значением.
/**
* @type {string | boolean}
*/
var sb; Вы можете указать типы массивов, используя различные синтаксисы:
/** @type {number[]} */
var ns;
/** @type {Array.<number>} */
var jsdoc;
/** @type {Array<number>} */
var nas; Вы также можете указать типы объектов-литералов. Например, объект со свойствами «a» (строка) и «b» (число) использует следующий синтаксис:
/** @type {{ a: string, b: number }} */
var var9; Вы можете указать похожие на мапы и массивы объекты, используя подписи индексов строк и чисел, используя либо стандартный синтаксис JSDoc, либо синтаксис TypeScript.
/**
* A map-like object that maps arbitrary `string` properties to `number`s.
*
* @type {Object.<string, number>}
*/
var stringToNumber;
/** @type {Object.<number, object>} */
var arrayLike; Два предыдущих типа эквивалентны типам TypeScript { [x: string]: number } и { [x: number]: any }. Компилятор понимает оба синтаксиса.
Вы можете указать типы функций, используя либо синтаксис TypeScript, либо синтаксис Google Closure:
/** @type {function(string, boolean): number} Closure syntax */
var sbn;
/** @type {(s: string, b: boolean) => number} TypeScript syntax */
var sbn2; Или вы можете просто использовать неопределённый тип Function:
/** @type {Function} */
var fn7;
/** @type {function} */
var fn6; Другие типы из Closure также работают:
/**
* @type {*} - can be 'any' type
*/
var star;
/**
* @type {?} - unknown type (same as 'any')
*/
var question; Приведения типов
TypeScript заимствует синтаксис приведения типов из Google Closure. Это позволяет вам приводить типы к другим типам, добавив тег @type перед любым выражением в скобках.
/**
* @type {number | string}
*/
var numberOrString = Math.random() < 0.5 ? "hello" : 100;
var typeAssertedNumber = /** @type {number} */ (numberOrString); Вы даже можете привести к типу const так же, как и в TypeScript:
let one = /** @type {const} */(1); Типы импорта
Вы можете импортировать объявления из других файлов с помощью импорта типов. Этот синтаксис специфичен для TypeScript и отличается от стандартного синтаксиса JSDoc:
// @filename: types.d.ts
export type Pet = {
name: string,
};
// @filename: main.js
/**
* @param {import("./types").Pet} p
*/
function walk(p) {
console.log(`Walking ${p.name}...`);
} Импорт типов может использоваться в объявлениях псевдонимов типов:
/**
* @typedef {import("./types").Pet} Pet
*/
/**
* @type {Pet}
*/
var myPet;
myPet.name; Импорт типов может использоваться для получения типа значения из модуля, если вы не знаете тип или если у него есть большой тип, который сложно набирать:
/**
* @type {typeof import("./accounts").userAccount}
*/
var x = require("./accounts").userAccount;
@param и @returns
@param использует тот же синтаксис типов, что и @type, но добавляет имя параметра. Параметр также может быть объявлен необязательным, заключив имя в квадратные скобки:
// 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
*/
function stringsStringStrings(p1, p2, p3, p4) {
// TODO
} Аналогично, для типа возвращаемого значения функции:
/**
* @return {PromiseLike<string>}
*/
function ps() {}
/**
* @returns {{ a: string, b: number }} - May use '@returns' as well as '@return'
*/
function ab() {}
@typedef, @callback, и @param
Вы можете определять сложные типы с помощью @typedef. Аналогичный синтаксис работает с @param.
/**
* @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;
specialTypeObject.prop3; Вы можете использовать либо object или Object в первой строке.
/**
* @typedef {object} SpecialType1 - 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
*/
/** @type {SpecialType1} */
var specialTypeObject1; @param позволяет использовать аналогичный синтаксис для одноразовых спецификаций типов. Обратите внимание, что имена вложенных свойств должны предваряться именем параметра:
/**
* @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, но вместо типа объекта указывает тип функции:
/**
* @callback Predicate
* @param {string} data
* @param {number} [index]
* @returns {boolean}
*/
/** @type {Predicate} */
const ok = (s) => !(s.length % 2); Конечно, любой из этих типов может быть объявлен с помощью синтаксиса TypeScript в однострочном @typedef:
/** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType */
/** @typedef {(data: string, index?: number) => boolean} Predicate */ @template
Вы можете объявить параметры типа с помощью тега @template. Это позволяет создавать функции, классы или типы, которые являются обобщёнными:
/**
* @template T
* @param {T} x - A generic parameter that flows through to the return type
* @returns {T}
*/
function id(x) {
return x;
}
const a = id("string");
const b = id(123);
const c = id({}); Используйте запятую или несколько тегов для объявления нескольких параметров типа:
/** * @template T,U,V * @template W,X */
Вы также можете указать ограничение типа перед именем параметра типа. Только первый параметр типа в списке ограничен:
/**
* @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) {
// ????
} Наконец, вы можете указать значение по умолчанию для параметра типа:
/** @template [T=object] */
class Cache {
/** @param {T} initial */
constructor(initial) {
}
}
let c = new Cache() Классы
Классы могут быть объявлены как классы ES6.
class C {
/**
* @param {number} data
*/
constructor(data) {
// property types can be inferred
this.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;
};
}
var c = new C(0);
// C should only be called with new, but
// because it is JavaScript, this is allowed and
// considered an 'any'.
var result = C(1); Они также могут быть объявлены как функции-конструкторы; используйте @constructor вместе с @this для этого.
Модификаторы свойств
@public, @private, и @protected работают точно так же, как public, private, и protected в TypeScript:
// @ts-check
class Car {
constructor() {
/** @private */
this.identifier = 100;
}
printIdentifier() {
console.log(this.identifier);
}
}
const c = new Car();
console.log(c.identifier); -
@publicвсегда подразумевается и может быть опущено, но означает, что к свойству можно обратиться из любой точки. -
@privateозначает, что к свойству можно обратиться только внутри содержащего класса. -
@protectedозначает, что к свойству можно обратиться только внутри содержащего класса и всех производных подклассов, но не на других экземплярах содержащего класса.
@public, @private, и @protected не работают в функциях-конструкторах.
@readonly
Модификатор @readonly гарантирует, что к свойству можно обратиться только при инициализации.
// @ts-check
class Car {
constructor() {
/** @readonly */
this.identifier = 100;
}
printIdentifier() {
console.log(this.identifier);
}
}
const c = new Car();
console.log(c.identifier); @override
@override работает так же, как и в TypeScript; используйте его для методов, переопределяющих метод из базового класса:
export class C {
m() { }
}
class D extends C {
/** @override */
m() { }
} Установите noImplicitOverride: true в tsconfig для проверки переопределений.
@extends
Когда JavaScript-классы наследуются от обобщённого базового класса, в JavaScript нет синтаксиса для передачи аргумента типа. Тег @extends позволяет это сделать:
/**
* @template T
* @extends {Set<T>}
*/
class SortableSet extends Set {
// ...
} Обратите внимание, что @extends работает только с классами. В настоящее время нет способа, чтобы функция-конструктор наследовалась от класса.
@implements
Также нет JavaScript-синтаксиса для реализации TypeScript-интерфейса. Тег @implements работает так же, как и в TypeScript:
/** @implements {Print} */
class TextBook {
print() {
// TODO
}
} @constructor
Компилятор выводит функции-конструкторы на основе назначений свойств this, но вы можете сделать проверки строже и улучшить предложения, если добавите тег @constructor:
/**
* @constructor
* @param {number} data
*/
function C(data) {
// property types can be inferred
this.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);
}
/**
* @param {string} s
*/
C.prototype.initialize = function (s) {
this.size = s.length;
};
var c = new C(0);
c.size;
var result = C(1); Примечание: Сообщения об ошибках отображаются только в базах кода JS с JSConfig и включённой опцией
checkJs.
С @constructor, this проверяется внутри функции-конструктора C, поэтому вы получите предложения для метода initialize и ошибку, если вы передадите ему число. Ваш редактор также может отображать предупреждения, если вы вызываете C вместо его создания.
К сожалению, это означает, что функции-конструкторы, которые также являются вызываемыми, не могут использовать @constructor.
@this
Компилятор обычно может определить тип this при наличии контекста. Когда этого нет, вы можете явно указать тип this с помощью тега @this:
/**
* @this {HTMLElement}
* @param {*} e
*/
function callbackForLater(e) {
this.clientHeight = parseInt(e); // should be fine!
} Документация
@deprecated
Когда функция, метод или свойство устарели, вы можете уведомить пользователей об этом, пометив их комментарием JSDoc /** @deprecated */. Эта информация отображается в списках автодополнения и как диагностическое сообщение, которое редакторы могут обрабатывать специально. В таком редакторе, как VS Code, устаревшие значения обычно отображаются штрихованным стилем так, как это.
/** @deprecated */
const apiV1 = {};
const apiV2 = {};
apiV;
@see
@see позволяет устанавливать ссылки на другие имена в вашей программе:
type Box<T> = { t: T }
/** @see Box for implementation details */
type Boxify<T> = { [K in keyof T]: Box<T> }; Некоторые редакторы превратят Box в ссылку, чтобы упростить переход туда и обратно.
@link
@link подобен @see, за исключением того, что его можно использовать внутри других тегов:
type Box<T> = { t: T }
/** @returns A {@link Box} containing the parameter. */
function box<U>(u: U): Box<U> {
return { t: u };
} Другие
@enum
Тег @enum позволяет создать литерал объекта, члены которого имеют указанный тип. В отличие от большинства литералов объектов в JavaScript, он не допускает других членов. @enum предназначен для совместимости с тегом @enum Google Closure.
/** @enum {number} */
const JSDocState = {
BeginningOfLine: 0,
SawAsterisk: 1,
SavingComments: 2,
};
JSDocState.SawAsterisk; Обратите внимание, что @enum значительно отличается от и намного проще, чем enum TypeScript. Однако, в отличие от перечислений TypeScript, @enum может иметь любой тип:
/** @enum {function(number): number} */
const MathFuncs = {
add1: (n) => n + 1,
id: (n) => -n,
sub1: (n) => n - 1,
};
MathFuncs.add1; @author
Вы можете указать автора элемента с помощью тега @author:
/** * Welcome to awesome.ts * @author Ian Awesome <i.am.awesome@example.com> */
Не забудьте заключить адрес электронной почты в угловые скобки. В противном случае, @example будет распарсен как новый тег.
Другие поддерживаемые шаблоны
var someObj = {
/**
* @param {string} param1 - JSDocs on property assignments work
*/
x: function (param1) {},
};
/**
* As do jsdocs 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 function expressions
* @param {number} x - A multiplier
*/
let myArrow = (x) => x * x;
/**
* Which means it works for function components in JSX too
* @param {{a: string, b: number}} props - Some param
*/
var fc = (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
*/
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();
} Неподдерживаемые шаблоны
Постфиксное присваивание (=) для типа свойства в литерале типа объекта не определяет необязательное свойство:
/**
* @type {{ a: string, b: number= }}
*/
var wrong;
/**
* Use postfix question on the property name instead:
* @type {{ a: string, b?: number }}
*/
var right; Нулевые типы имеют смысл только если strictNullChecks включен:
/**
* @type {?number}
* With strictNullChecks: true -- number | null
* With strictNullChecks: false -- number
*/
var nullable; Встроенный синтаксис TypeScript — это союз типов:
/**
* @type {number | null}
* With strictNullChecks: true -- number | null
* With strictNullChecks: false -- number
*/
var unionNullable; Необязательные типы не имеют смысла и обрабатываются так же, как их исходный тип:
/**
* @type {!number}
* Just has type number
*/
var normal; В отличие от системы типов JSDoc, TypeScript позволяет только отмечать типы как содержащие null или не содержащие. Нет явного отсутствия возможности быть null — если strictNullChecks включен, то number не является null. Если он выключен, то number является null.
Неподдерживаемые теги
TypeScript игнорирует любые неподдерживаемые теги JSDoc.
Следующие теги имеют открытые вопросы для их поддержки:
-
@const(номер проблемы 19672) -
@inheritdoc(номер проблемы 23215) -
@memberof(номер проблемы 7237) -
@yields(номер проблемы 23857)
© 2012-2023 Microsoft
Licensed under the Apache License, Version 2.0.
https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html