Поддерживаемый JSDoc
В следующем списке перечислены поддерживаемые в настоящее время аннотации JSDoc, которые можно использовать для добавления информации о типе в файлы JavaScript.
Обратите внимание, что в списке ниже нет тегов (например,@async) пока не поддерживаются.
@type-
@param(or@argor@argument) -
@returns(or@return) @typedef@callback@template-
@class(or@constructor) @this-
@extends(or@augments) @enum
Значения, которые они представляют, обычно совпадают со значениями, указанными выше на usejsdoc.org или их надмножестве. Код ниже описывает их различия и дает несколько примеров.
@type
можно использовать@typeОтмечайте имя типа и ссылайтесь на него (необработанный тип, тип, объявленный в TypeScript или в JSDoc).@typedefтег) может использовать любой тип TypeScript и большинство типов JSDoc.
/**
* @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Можно указать типы объединения, например,stringа такжеbooleanтип союза.
/**
* @type {(string | boolean)}
*/
var sb;
Обратите внимание, что скобки необязательны.
/**
* @type {string | boolean}
*/
var sb;
Существует несколько способов указать типы массивов:
/** @type {number[]} */
var ns;
/** @type {Array.<number>} */
var nds;
/** @type {Array<number>} */
var nas;
Вы также можете указать тип литерала объекта. Например, сa(строка) иb(числовое) свойство объекта, используя следующий синтаксис:
/** @type {{ a: string, b: number }} */
var var9;
Может быть указан с использованием строковых и числовых подписей индексаmap-likeа такжеarray-likeобъекта, используя стандартный синтаксис 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 или 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;
Также могут использоваться другие типы закрытия:
/**
* @type {*} - can be 'any' type
*/
var star;
/**
* @type {?} - unknown type (same as 'any')
*/
var question;
конвертировать
TypeScript заимствует синтаксис преобразования из Closure. использовать перед выражением в скобках@typeФлаги, которые могут преобразовывать один тип в другой
/**
* @type {number | string}
*/
var numberOrString = Math.random() < 0.5 ? "hello" : 100;
var typeAssertedNumber = /** @type {number} */ (numberOrString)
тип импорта
Объявления можно импортировать из других файлов, используя типы импорта. Этот синтаксис специфичен для TypeScript и отличается от стандарта JSDoc:
/**
* @param p { import("./a").Pet }
*/
function walk(p) {
console.log(`Walking ${p.name}...`);
}
Импортированные типы также можно использовать в объявлениях псевдонимов типов:
/**
* @typedef { import("./a").Pet } Pet
*/
/**
* @type {Pet}
*/
var myPet;
myPet.name;
Импортированные типы можно использовать для типов, которые получают значение из модуля.
/**
* @type {typeof import("./a").x }
*/
var x = require("./a").x;
@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 (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
}
Тип возвращаемого значения функции аналогичен:
/**
* @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;
можно использовать в первой строкеobjectилиObject.
/**
* @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Допускается аналогичный синтаксис. Обратите внимание, что имена вложенных свойств должны начинаться с имени параметра:
/**
* @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
* @return {T}
*/
function id(x){ return x }
Объявите несколько параметров типа с запятыми или несколькими токенами:
/**
* @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) {
// ????
}
@constructor
Компилятор проходитthisНазначение свойств для вывода конструктора, но можно сделать проверку строже, подсказку дружелюбнее, можно добавить@constructorотметка:
/**
* @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
пройти через@constructor,thisбудет в конструктореCпроверено, так что вы находитесь вinitializeметод, и если вы передадите число, вы также получите сообщение об ошибке. Если вы позвоните напрямуюCвместо его построения вы также получите ошибку.
К сожалению, это означает, что конструкторы, которые могут создаваться и вызываться напрямую, не могут быть использованы.@constructor.
@this
Компилятор обычно может сделать вывод из контекстаthisтип. но вы можете использовать@thisчтобы явно указать его тип:
/**
* @this {HTMLElement}
* @param {*} e
*/
function callbackForLater(e) {
this.clientHeight = parseInt(e) // should be fine!
}
@extends
Когда класс JavaScript расширяет базовый класс, негде указать тип параметра типа. а также@extendsМаркеры обеспечивают такой способ:
/**
* @template T
* @extends {Set<T>}
*/
class SortableSet extends Set {
// ...
}
Уведомление@extendsДействует только на классы. В настоящее время конструктор не может быть реализован.
@enum
@enumТеги позволяют создать литерал объекта, члены которого относятся к определенному типу. В отличие от большинства литералов объектов в JavaScript, он не позволяет добавлять дополнительные элементы.
/** @enum {number} */
const JSDocState = {
BeginningOfLine: 0,
SawAsterisk: 1,
SavingComments: 2,
}
Уведомление@enumс помощью машинописного текста@enumСовсем другое, это проще. Однако, в отличие от перечислений TypeScript,@enumМожет быть любого типа:
/** @enum {function(number): number} */
const Math = {
add1: n => n + 1,
id: n => -n,
sub1: n => n - 1,
}
больше примеров
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) => <div>{test.a.charAt(0)}</div>;
/**
* 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();
}
известный неподдерживаемый режим
Невозможно рассматривать объект как тип в пространстве значений, если только объект не создает тип, например конструктор.
function aNormalFunction() {
}
/**
* @type {aNormalFunction}
*/
var wrong;
/**
* Use 'typeof' instead:
* @type {typeof aNormalFunction}
*/
var right;
на литеральные свойства объекта=Суффикс указать нельзя. Этот атрибут является необязательным:
/**
* @type {{ a: string, b: number= }}
*/
var wrong;
/**
* Use postfix question on the property name instead:
* @type {{ a: string, b?: number }}
*/
var right;
Nullableпечатать только при включенииstrictNullChecksЭто работает только при проверке:
/**
* @type {?number}
* With strictNullChecks: true -- number | null
* With strictNullChecks: off -- number
*/
var nullable;
Non-nullableТипы не имеют смысла, рассматриваются как их исходный тип:
/**
* @type {!number}
* Just has type number
*/
var normal;
В отличие от системы типов JSDoc, TypeScript позволяет помечать типы только как исключенные из пакетов.null. не чистоNon-nullable-- если включеноstrictNullChecks,Такnumberправильно и неправильноnullиз. Если не включено, тоnumberвозможно дляnullиз.