Como documentar um tipo de string em jsdoc com valores possíveis limitados

101

Estou tendo uma função que aceita um parâmetro de string. Este parâmetro pode ter apenas um dos poucos valores possíveis definidos. Qual é a melhor maneira de documentar o mesmo? O shapeType deve ser definido como enum ou TypeDef ou algo mais?

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

A segunda parte do problema é que os valores possíveis de shapeTypenão são conhecidos no arquivo que define shapeTypeo que você sugere. Existem vários arquivos contribuídos por vários desenvolvedores que podem adicionar aos valores possíveis de shapeType.

PS: Estou usando jsdoc3

Shamasis Bhattacharya
fonte
O problema de vários arquivos torna isso difícil. Eu costumo ver um enumpara a definição e uma união para o parâmetro função: ShapeType|string. No entanto, enums não suportam a adição de subtipos após a declaração no compilador Closure.
Chad Killingsworth
@ChadKillingsworth Eu entendo o que você quer dizer. Estou preso em um ponto em que quero definir um conjunto de propriedades (digamos, um objeto que funciona como parâmetro de construção de uma classe). É bom ter todas as propriedades da construção definidas em um local. Infelizmente, meu código tem vários módulos que contribuem para essas propriedades de construção. Fazer algo como um mixin ou subclassificar o proprietário seria exagerar! Como tal, se eu pudesse simplesmente injetar em uma definição de lista de propriedades, seria ótimo.
Shamasis Bhattacharya
Outro problema semelhante que estou enfrentando, mas com listagem de propriedades distribuídas é stackoverflow.com/questions/19113571/…
Shamasis Bhattacharya
Todas as soluções abaixo nos forçam a criar um Enum. Há uma solicitação de recurso ativo no GitHub para tornar esse processo muito mais fácil: github.com/jsdoc3/jsdoc/issues/629 . Portanto, qualquer pessoa que goste provavelmente deveria dar um jeito.
B12Toaster

Respostas:

27

Que tal declarar um enum fictício:

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

Você precisa pelo menos declarar o enum para JSDOC, para isso, no entanto. Mas o código está limpo e você obtém o preenchimento automático no WebStorm.

O problema de vários arquivos, porém, não pode ser resolvido desta forma.

Sebastian
fonte
Sim. A abordagem de enumeração é a única maneira utilizável que vejo. De qualquer forma, aceito essa como a única resposta utilizável - já que o problema de vários arquivos é outra história!
Shamasis Bhattacharya
O problema com essa abordagem é que ela não permite documentar os valores individuais. Tenho um problema com o JSDoc. github.com/jsdoc3/jsdoc/issues/1065
Gajus
118

No final de 2014 em jsdoc3, você tem a possibilidade de escrever:

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

É claro que isso não será tão reutilizável quanto um enum dedicado, mas em muitos casos um enum fictício é um exagero se for usado apenas por uma função.

Veja também: https://github.com/jsdoc3/jsdoc/issues/629#issue-31314808

B12Toaster
fonte
4
Esta é uma solução melhor se você souber que o tipo de parâmetro nunca mudará.
Luca Steeb
1
Melhor solução para isso na minha opinião! Obrigado.
AJC24 de
29

A respeito:

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

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

insira a descrição da imagem aqui

puemos
fonte
9

Não acho que haja uma maneira formal de escrever valores permitidos no JSDoc .

Você certamente pode escrever algo @param {String('up'|'down'|'left'|'right')}como o usuário b12toaster mencionado.

insira a descrição da imagem aqui

Mas, tomando a referência de APIDocjs , aqui está o que uso para escrever valores restritos, também conhecidos como valores permitidos .

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

Sim, estou usando o ES6.

Alan dong
fonte
0

É assim que o Closure Compiler o suporta: você pode usar "@enum" para definir um tipo restrito. Na verdade, você não precisa definir os valores na definição de enum. Por exemplo, posso definir um tipo "inteiro" como:

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

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

Int é geralmente atribuível a "número" (é um número), mas "número" não pode ser atribuído a "Int" sem alguma coerção (um elenco).

John
fonte
Mas isso não restringe os valores possíveis de Int. Essa é a parte que não tenho certeza se é possível.
Chad Killingsworth
Ele faz tanto quanto qualquer outra anotação de tipo ou enum em JS. A restrição vem de como você escreve o código: todo "elenco" é uma bandeira vermelha. Se você limitar os lançamentos às fábricas de valor, obterá o que deseja: você não pode atribuir 'número' a 'Int' sem um aviso.
João,
Ele ainda não restringe os valores de {Int}. :-(
Shamasis Bhattacharya
Claro que sim, você restringe o valor de Int limitando como ele é criado e a restrição é feita quando o valor é criado. Um número bruto não pode ser atribuído, o que é tudo de que você precisa.
João,