Cómo documentar un tipo de cadena en jsdoc con valores posibles limitados

96

Tengo una función que acepta un parámetro de cadena. Este parámetro solo puede tener uno de los pocos valores posibles definidos. ¿Cuál es la mejor forma de documentar lo mismo? ¿Debe shapeType definirse como enum o TypeDef o algo más?

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;
};

La segunda parte del problema es que los posibles valores de shapeTypeno se conocen en el archivo que define shapeTypecomo lo que sugiera. Hay varios archivos aportados por varios desarrolladores que podrían agregar a los posibles valores de shapeType.

PD: estoy usando jsdoc3

Shamasis Bhattacharya
fuente
El problema de los archivos múltiples dificulta esto. Por lo general veo una enumpara la definición y una unión para el parámetro de la función: ShapeType|string. Sin embargo, las enumeraciones no admiten la adición de subtipos después de la declaración en el compilador de cierre.
Chad Killingsworth
@ChadKillingsworth Veo lo que quieres decir. Estoy atascado en un punto en el que quiero definir un conjunto de propiedades (digamos un objeto que va como parámetro de construcción de una clase). Está muy bien que todas las propiedades de la construcción se hayan definido en un solo lugar. Desafortunadamente, mi código tiene varios módulos que contribuyen a esas propiedades de construcción. ¡Hacer algo como un mixin o subclasificar a los propietarios sería ir por la borda! Como tal, si pudiera simplemente inyectar en una definición de lista de propiedades, sería genial.
Shamasis Bhattacharya
Otro problema similar al que me enfrento, pero con la lista de propiedades distribuidas es stackoverflow.com/questions/19113571/…
Shamasis Bhattacharya
Todas las soluciones a continuación nos obligan a crear una enumeración. Hay una solicitud de función activa en GitHub para facilitar mucho este proceso: github.com/jsdoc3/jsdoc/issues/629 . Entonces, cualquiera a quien le guste probablemente debería golpearlo.
B12Toaster

Respuestas:

26

¿Qué tal declarar una enumeración ficticia?

/**
 * 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)

Sin embargo, debe declarar al menos la enumeración a JSDOC, para esto. Pero el código está limpio y se completa automáticamente en WebStorm.

Sin embargo, el problema de varios archivos no se puede resolver de esta manera.

Sebastián
fuente
Si. El enfoque de enumeración es la única forma utilizable que veo. De todos modos, acepto esto como la única respuesta utilizable, ¡ya que el problema de múltiples archivos es otra historia!
Shamasis Bhattacharya
El problema con este enfoque es que no permite documentar los valores individuales. Tengo un problema con JSDoc. github.com/jsdoc3/jsdoc/issues/1065
Gajus
112

A finales de 2014 en jsdoc3 tiene la posibilidad de escribir:

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

Por supuesto, esto no será tan reutilizable como una enumeración dedicada, pero en muchos casos una enumeración ficticia es una exageración si solo la usa una función.

Véase también: https://github.com/jsdoc3/jsdoc/issues/629#issue-31314808

B12 Tostadora
fuente
4
Esta es una mejor solución si sabe que el tipo de parámetro nunca cambiará.
Luca Steeb
1
¡La mejor solución para esto en mi opinión! Gracias.
AJC24
26

Qué pasa:

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

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

ingrese la descripción de la imagen aquí

puemos
fuente
9

No creo que haya una forma formal de escribir valores permitidos en JSDoc .

Ciertamente puede escribir algo como el @param {String('up'|'down'|'left'|'right')}que mencionó el usuario b12toaster .

ingrese la descripción de la imagen aquí

Pero, tomando como referencia APIDocjs , esto es lo que uso para escribir valores restringidos, también conocidos como allowedValues .

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

Oh, sí, estoy usando ES6.

Alan Dong
fuente
0

Así es como el compilador de cierre lo admite: puede usar "@enum" para definir un tipo restringido. En realidad, no tiene que definir los valores en la definición de enumeración. Por ejemplo, podría definir un tipo "entero" como:

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

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

Int generalmente se puede asignar a "number" (es un número) pero "number" no se puede asignar a "Int" sin alguna coerción (un elenco).

Juan
fuente
Pero eso no restringe los posibles valores de Int. Esa es la parte que no estoy seguro de que sea posible.
Chad Killingsworth
Hace tanto como cualquier otro tipo de anotación o enumeración en JS. La restricción proviene de cómo se escribe el código: cada "elenco" es una señal de alerta. Si limita los lanzamientos para valorar las fábricas, obtiene lo que desea: no puede asignar 'número' a 'Int' sin una advertencia.
Juan
Todavía no restringe los valores de {Int}. :-(
Shamasis Bhattacharya
Claro que sí, restringe el valor de Int limitando cómo se crea y la restricción se realiza cuando se crea el valor. No se puede asignar un número sin procesar, que es todo lo que necesita.
John