es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo escribir un JSDoc para un objeto con diferentes tipos de claves?

El API de JSDoc dice que se pueden documentar objetos como sigue:

{Object.<string, number>}

y se pueden documentar varios tipos:

{(number|boolean)}

Pero si intento especificar un objeto que pueda tener cadenas O números como clave, no funciona. VSCode/JSDoc simplemente informa el tipo como ‘any’.

VSCode no entiende:

/**
* Object with string or number for keys
* @param {Object.<(string|number), any>} Container
*/

También lo he intentado con @typedef, o definiendo la clave en su propio @typedef sin ningún efecto.

Como estoy usando “&” para obtener una intersección de tipos (como {Object.<string, any> & {‘foo’: number}}) no quiero tener que usar el boolean o decir:

/**
* Object with string or number for keys
* @param {(Object.<string, any>|Object.<number, any>) & {‘foo’: number}} Container
*/

El tipo documentado termina pareciendo algo como:

type Container = ({
[x: string]: any;
} & {
‘foo’: number;
}) | ({
[x: number]: any;
} & {
‘foo’: number;
})

Lo cual es innecesariamente redundante.

¿Existe alguna forma de documentar esto con una salida más sucinta?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Documentando Objetos con Tipos de Claves Mixtas en JSDoc

    JSDoc permite documentar objetos usando la siguiente sintaxis:

    {Object.<string, number="">}
    

    Esto documenta un objeto con claves de tipo string y valores de tipo número. Adicionalmente, JSDoc permite documentar múltiples tipos usando el operador ‘|’ :

    {(number|boolean)}
    

    Sin embargo, especificar un objeto con claves mixtas (es decir, string o número) usando la sintaxis anterior no funciona. El tipo simplemente es reportado como ‘any’ por VSCode/JSDoc.

    Para resolver esto, una posible solución es usar el operador ‘|’ para documentar objetos con claves string y numéricas por separado:

    /**
     * Objeto con claves string
     * @typedef {Object.<string, any="">} StringObject
     */
    
     /**
     * Objeto con claves numéricas
     * @typedef {Object.<number, any="">} NumberObject
     */
    
    /**
     * Objeto con claves string o numéricas
     * @param {(StringObject|NumberObject)&{'foo':number}} Contenedor
     */
    

    Este método utiliza ‘typedef’ para crear tipos separados para objetos con claves string y numéricas, y luego los combina usando el operador ‘|’. Adicionalmente, se utiliza el operador ‘&’ para agregar la clave ‘foo’ a la definición final del tipo.

    Esto resulta en una salida más concisa:

    type Contenedor = ({[x: string]: any;} | {[x: number]: any;}) & {'foo':number;}
    

    Aunque esto aún puede parecer verboso, es más conciso que el método anterior de usar ‘Object.<string, any=””>|Object.<number, any=””>’, especialmente cuando se trata con tipos más complejos.</number,></string,></number,></string,></string,>

Comments are closed.