Controlador de fuego1847
Digamos que tengo un archivo llamado “File1.js”. En este archivo, exporto un objeto de objetos y le doy a cada objeto un typedef, así.
/**
* My typedef for each object.
* @typedef {Object} MyObject1
* @property {String} username Your username
* @property {String} realname Your real name.
* @property {boolean} isUnique Are you unique as a person?
*/
module.exports = {
/**
* Person One!
* @type {MyObject1}
*/
myperson: {
username: 'TheDragonSlayer',
realname: 'George',
isUnique: true
},
/**
* Person Two!
* @type {MyObject1}
*/
myperson2: {
username: 'BobMagee',
realname: 'Bob',
isUnique: false
}
}
Ahora, en un archivo llamado “File2.js”, hago referencia a este objeto en un constructor y lo establezco en un nuevo MyObject1
.
const persons = require('./File1.js');
class File2 {
constructor(options = {}) {
/**
* The person for this file.
* @type {MyObject1}
*/
this.person = options.person ? persons[options.person] : persons.myperson2;
}
}
module.exports = File2;
Uso Visual Studio Code para desarrollar, por lo que al presionar Ctrl+Espacio obtengo IntelliSense. Dentro del archivo uno y mientras hago los objetos person, IntelliSense me dice que el nombre de usuario es una cadena, realname es una cadena e isUnique es un valor booleano. Pero, cuando entro en el archivo 2 y hago referencia a la persona recién creada a través de this.person
al escribir this.person.username
no presenta el resultado esperado de “Nombre de usuario: Cadena”.
¿Es posible usar el typedef? MyObject1
en File2 en vanilla Node.js, ¿o no tengo suerte?
Editar: con algo más de información, pude encontrar respuestas con @export y @import para TypeScript, así como una especie de etiqueta que también probé. Todo lo cual fue en vano. También intenté marcar File1.js como @module y hacer module:mymodule~MyMethod
pero cada vez que lo hacía, simplemente marcaba this.person como NodeModule en lugar del método en sí.
Importe el tipo declarado en su archivo File2.js
usando la función import
.
const persons = require('./File1.js');
/**
* @typedef {import('./File1.js').MyObject1} MyObject1
*/
class File2 {
...
Esto funciona para mi.
-
¡Impresionante! ¡Esto realmente lo arregló! ¡Muchas gracias!
– Controlador de fuego1847
17 de octubre de 2018 a las 5:11
-
Esta es una sintaxis específica de TypeScript. Vota por github.com/jsdoc/jsdoc/issues/1645.
– cañada-84
28 de mayo de 2020 a las 10:42
-
Documentos oficiales para tipos de importación: typescriptlang.org/docs/handbook/…
– Georgiy Bujarov
22 de noviembre de 2021 a las 10:41
-
Cualquier forma de no escribir repetidamente
import('./File1.js')
? (si necesito, por ejemplo, tambiénfile1.MyObject2
yfile1.MyObjectN
). – Haciendo@typedef {import('./File1.js')} file1
y@typedef {file1.MyObject2} MyObject2
MyObject2 solo tiene alias y pierde detalles de definición, se marca como/*unresolved*/ any
.– Kamapluma
29 ago 2022 a las 16:00
Otra cosa que descubrí trabajando es exportar y vaciar el modelo y luego usarlo como referencia a los tipos:
tipos.js:
/**
* @typedef MyType
* @prop {string} name
* @prop {string} description
*/
export const Types = {}
Luego, en sus otros archivos, puede importar eso y tener los tipos de ese objeto ficticio:
Archivo1.js
import * as Types from "./types.js"
/** @type {Types.MyType} */
const myVar = { name : 'Roy', description : 'abc123'};
ventajas:
- mucho “limpio” – menos código para escribir
- solo hay que importar una vez
contras:
- un poco raro
- no idiomático
- es posible que obtenga el error:
Esta importación nunca se usa como un valor y debe usar ‘tipo de importación’ porque ‘importsNotUsedAsValues’ está establecido en ‘error’
Si tienes esa bandera puesta.
Para sortear esa advertencia, solo necesita deshabilitarla con un ts-ignore:
// @ts-ignore
import * as Types from "./types.js";
Querías decir
@typedef
en lugar de@typdef
en Archivo1?– Pedro G.
14/04/2018 a las 22:42
@PeterG ¡Sí, lo siento!
– Controlador de fuego1847
14/04/2018 a las 22:47
Puede ser solo una cuestión de qué tan inteligente es Intellisense en lugar de una cosa de JSDoc. Usando WebStorm IDE, encontré que este escenario funciona como se esperaba, pero a menudo encuentro límites en el soporte de JSDoc; por ejemplo, no funciona como se esperaba cuando @typedef está en un proyecto de dependencia.
–Justin Emery
19 de abril de 2018 a las 8:55
Hay un comentario a este efecto en la respuesta a continuación, pero
import("some-module")
es compatible con Typescript pero es no JSDoc oficial.– Codificador
21 de enero de 2021 a las 11:22
También usando
import "./types.js"
y @typedef en el archivo types.js funciona para mí.– aderchox
15/09/2022 a las 17:08