Come documentare un tipo di stringa in jsdoc con valori possibili limitati


96

Sto avendo una funzione che accetta un parametro stringa. Questo parametro può avere solo uno dei pochi valori possibili definiti. Qual è il modo migliore per documentare lo stesso? ShapeType dovrebbe essere definito come enum o TypeDef o qualcos'altro?

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 seconda parte del problema è che i possibili valori di shapeTypenon sono noti nel file che definisce shapeTypecome qualunque cosa tu suggerisca. Ci sono più file forniti da diversi sviluppatori che potrebbero aggiungere ai possibili valori di shapeType.

PS: sto usando jsdoc3


Il problema di più file rende questo difficile. Io di solito vedo una enumper la definizione e l'unione per il parametro della funzione: ShapeType|string. Tuttavia le enumerazioni non supportano l'aggiunta di sottotipi dopo la dichiarazione in Closure-compiler.
Chad Killingsworth,

@ChadKillingsworth Capisco cosa intendi. Sono bloccato a un punto in cui voglio definire un insieme di proprietà (diciamo un oggetto che funge da parametro di costruzione di una classe). Va bene se tutte le proprietà della costruzione sono state definite in un'unica posizione. Sfortunatamente, il mio codice ha un numero di moduli che contribuiscono a tali proprietà di costruzione. Fare qualcosa come un mixin o una sottoclasse del proprietario sarebbe esagerato! In quanto tale, se potessi semplicemente iniettare una definizione di elenco di proprietà sarebbe fantastico.
Shamasis Bhattacharya

Un altro problema simile che sto affrontando, ma con elenco di proprietà distribuita è stackoverflow.com/questions/19113571/...
Shamasis Bhattacharya

Tutte le soluzioni seguenti ci costringono a creare un Enum. C'è una richiesta di funzionalità attiva su GitHub per rendere questo processo molto più semplice: github.com/jsdoc3/jsdoc/issues/629 . Quindi chiunque a cui piaccia dovrebbe probabilmente respingerlo.
B12Toaster

Risposte:


26

Che ne dici di dichiarare un'enumerazione fittizia:

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

Per questo, però, devi almeno dichiarare l'enumerazione a JSDOC. Ma il codice è pulito e ottieni il completamento automatico in WebStorm.

Tuttavia, il problema dei file multipli non può essere risolto in questo modo.


Sì. L'approccio dell'enumerazione è l'unico modo utilizzabile che vedo. Ad ogni modo, lo accetto come l'unica risposta utilizzabile, poiché il problema multi-file è tutta un'altra storia!
Shamasis Bhattacharya

Il problema con questo approccio è che non consente di documentare i singoli valori. Ho un problema con JSDoc. github.com/jsdoc3/jsdoc/issues/1065
Gajus

112

Alla fine del 2014 in jsdoc3 hai la possibilità di scrivere:

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

Ovviamente questo non sarà riutilizzabile come un'enumerazione dedicata, ma in molti casi un'enumerazione fittizia è eccessiva se viene utilizzata solo da una funzione.

Vedi anche: https://github.com/jsdoc3/jsdoc/issues/629#issue-31314808


4
Questa è una soluzione migliore se sai che il tipo di parametro non cambierà mai.
Luca Steeb

1
La migliore soluzione a questo a mio avviso! Grazie.
AJC24

26

Che dire:

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

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

inserisci qui la descrizione dell'immagine


9

Non credo che esista un modo formale di scrivere i valori consentiti in JSDoc .

Puoi certamente scrivere qualcosa @param {String('up'|'down'|'left'|'right')}come l'utente citato b12toaster .

inserisci qui la descrizione dell'immagine

Ma, prendendo riferimento da APIDocjs , ecco cosa uso per scrivere valori vincolati, noti anche come valori consentiti .

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

Oh sì, sto usando ES6.


0

Questo è il modo in cui il Closure Compiler lo supporta: puoi usare "@enum" per definire un tipo limitato. In realtà non è necessario definire i valori nella definizione di enum. Ad esempio, potrei definire un tipo "intero" come:

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

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

Int è generalmente assegnabile a "numero" (è un numero) ma "numero" non è assegnabile a "Int" senza qualche coercizione (un cast).


Ma ciò non limita i possibili valori di Int. Questa è la parte che non sono sicuro sia possibile.
Chad Killingsworth

Fa quanto qualsiasi altro tipo di annotazione o enumerazione in JS. La restrizione deriva da come scrivi il codice: ogni "cast" è una bandiera rossa. Se limiti i cast alle fabbriche di valore, ottieni ciò che desideri: non puoi assegnare "numero" a "Int" senza preavviso.
Giovanni

Ancora non limita i valori di {Int}. :-(
Shamasis Bhattacharya

Certo, restringi il valore di Int limitando il modo in cui viene creato e la restrizione viene eseguita quando il valore viene creato. Non è possibile assegnare un numero grezzo che è tutto ciò di cui hai bisogno.
John
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.