Как задокументировать строковый тип в jsdoc с ограниченными возможными значениями

96

У меня есть функция, которая принимает один строковый параметр. Этот параметр может иметь только одно из нескольких определенных возможных значений. Как лучше всего задокументировать то же самое? Следует ли определять shapeType как enum, TypeDef или что-то еще?

Shape.prototype.create = function (shapeType) {
    // shapeType can be "rect", "circle" or "ellipse"...
    this.type = shapeType;
};

Shape.prototype.getType = function (shapeType) {
    // shapeType can be "rect", "circle" or "ellipse"...
    return this.type;
};

Вторая часть проблемы заключается в том, что возможные значения shapeTypeнеизвестны в файле, который определяет shapeTypeвсе, что вы предлагаете. Есть несколько файлов, добавленных несколькими разработчиками, которые могут добавить к возможным значениям shapeType.

PS: Я использую jsdoc3

Шамасис Бхаттачарья
источник
Проблема с несколькими файлами усложняет эту задачу. Я обычно вижу enumдля определения и объединения для параметра функции: ShapeType|string. Однако перечисления не поддерживают добавление подтипов после объявления в компиляторе Closure.
Чад Киллингсворт,
@ChadKillingsworth, я понимаю, о чем вы. Я застрял в точке, где я хочу определить набор свойств (скажем, объект, который является параметром конструкции класса). Хорошо, если все свойства постройки определены в одном месте. К сожалению, в моем коде есть несколько модулей, влияющих на свойства конструкции. Делать что-то вроде миксина или подкласса имущих было бы слишком сложно! Таким образом, если бы я мог просто ввести определение списка свойств, было бы здорово.
Шамасис Бхаттачарья
Еще одна похожая проблема, с которой я столкнулся, но с распределенным списком свойств, - stackoverflow.com/questions/19113571/…
Шамасис Бхаттачарья 01
Все приведенные ниже решения вынуждают нас создать Enum. На GitHub есть активный запрос функции, который значительно упрощает этот процесс: github.com/jsdoc3/jsdoc/issues/629 . Так что любой, кому это нравится, вероятно, должен его поднять.
B12Toaster 07

Ответы:

26

Как насчет объявления фиктивного перечисления:

/**
 * Enum string values.
 * @enum {string}
 */
Enumeration = {
    ONE: "The number one",
    TWO: "A second number"
};

/**
 * Sample.
 * @param {Enumeration} a one of the enumeration values.
 */
Bar.prototype.sample = function(a) {};


b = new Bar();

bar.sample(Enumeration.ONE)

Однако для этого вам нужно хотя бы объявить перечисление в JSDOC. Но код чистый, и вы получаете автозаполнение в WebStorm.

Однако проблема с несколькими файлами не может быть решена таким образом.

Себастьян
источник
Да. Я вижу, что метод перечисления - единственный приемлемый способ. В любом случае, я принимаю это как единственный полезный ответ, поскольку проблема с несколькими файлами - это совсем другая история!
Шамасис Бхаттачарья
Проблема с этим подходом заключается в том, что он не позволяет задокументировать отдельные значения. У меня проблема с JSDoc. github.com/jsdoc3/jsdoc/issues/1065
Gajus
112

По состоянию на конец 2014 года в jsdoc3 у вас есть возможность написать:

/**
 * @param {('rect'|'circle'|'ellipse')} shapeType - The allowed type of the shape
 */
Shape.prototype.getType = function (shapeType) {
  return this.type;
};

Конечно, это будет не так многоразово, как выделенное перечисление, но во многих случаях фиктивное перечисление является излишним, если оно используется только одной функцией.

См. Также: https://github.com/jsdoc3/jsdoc/issues/629#issue-31314808

B12Toaster
источник
4
Это лучшее решение, если вы знаете, что тип параметра никогда не изменится.
Лука Стиб,
1
На мой взгляд, лучшее решение этой проблемы! Спасибо.
AJC24,
26

Что о:

/**
 * @typedef {"keyvalue" | "bar" | "timeseries" | "pie" | "table"} MetricFormat
 */

/**
 * @param format {MetricFormat}
 */
export function fetchMetric(format) {
    return fetch(`/matric}`, format);
}

введите описание изображения здесь

пуэмос
источник
9

Я не думаю, что существует формальный способ записи разрешенных значений в JSDoc .

Вы, конечно, можете написать что-то @param {String('up'|'down'|'left'|'right')}вроде упомянутого пользователя b12toaster .

введите описание изображения здесь

Но, взяв ссылку из APIDocjs , вот что я использую для записи ограниченных значений, также известных как allowedValues .

/**
 * Set the arrow position of the tooltip
 * @param {String='up','down','left','right'} position pointer position
 */
setPosition(position='left'){
  // YOUR OWN CODE
}

Ах да, я использую ES6.

Алан Донг
источник
0

Это то, как компилятор Closure поддерживает это: вы можете использовать «@enum» для определения ограниченного типа. На самом деле вам не нужно определять значения в определении перечисления. Например, я мог бы определить «целочисленный» тип, например:

/** @enum {number} */
var Int = {};

/** @return {Int} */
function toInt(val) {
  return /** @type {Int} */ (val|0);
}

Int обычно присваивается «number» (это число), но «number» не может быть присвоено «Int» без некоторого принуждения (приведения).

Джон
источник
Но это не ограничивает возможные значения Int. Я не уверен, что это возможно.
Чад Киллингсворт
Он делает то же самое, что и аннотация любого другого типа или перечисление в JS. Ограничение связано с тем, как вы пишете код: каждое «приведение» - это красный флаг. Если вы ограничите приведение значений фабриками значений, вы получите то, что хотите: вы не можете присвоить 'number' значение 'Int' без предупреждения.
Джон
Он по-прежнему не ограничивает значения {Int}. :-(
Шамасис Бхаттачарья 08
Конечно, вы ограничиваете значение Int, ограничивая способ его создания, и ограничение выполняется при создании значения. Необработанный номер не может быть назначен, и это все, что вам нужно.
Джон