javascript - Cum să „importați” un typedef dintr-un fișier în altul în JSDoc folosind VS Code?
Să spunem că am un fișier numit „File1.js”. În acest fișier, export un obiect de obiecte și dau fiecărui obiect un tip definit, astfel.
/**
* 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
}
}
Acum, într-un fișier numit "File2.js", fac referire la acest obiect într-un constructor și îl setez la un nou 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;
Folosesc Visual Studio Code pentru a dezvolta, așa că apăsând Ctrl+Space primesc IntelliSense. În cadrul fișierului unul și în timp ce creez obiectele persoană, IntelliSense îmi spune că username este un string, realname este un string și isUnique este un boolean. Dar, când merg în fișierul doi și fac referire la persoana nou creată prin this.person, la tastarea this.person.username nu apare rezultatul așteptat „Username: String”.
Este posibil să folosesc typedef MyObject1 în File2 în Node.js pur, sau sunt ghinionist?
Editare: Cu câteva informații suplimentare, am reușit să găsesc răspunsuri cu @export și @import pentru TypeScript, precum și un fel de etichetă pe care am încercat-o și eu. Toate fără niciun rezultat. Am încercat, de asemenea, să marchezi File1.js ca @module și să folosesc module:mymodule~MyMethod, dar de fiecare dată când făceam asta, doar marca this.person ca NodeModule în loc de metoda în sine.
Răspuns #1
Importă tipul declarat în fișierul tău File2.js folosind funcția import.
const persons = require('./File1.js');
/**
* @typedef {import('./File1.js').MyObject1} MyObject1
*/
class File2 {
...
Funcționează pentru mine.
Răspunsul #2
Un alt lucru pe care l-am descoperit lucrând este să export un model gol și apoi să îl folosesc ca referință pentru tipuri:
types.js:
/**
* @typedef MyType
* @prop {string} name
* @prop {string} description
*/
export const Types = {}
Apoi, în celelalte fișiere poți importa asta și să ai tipurile din acel obiect fictiv:
Fișier1.js
import * as Types from "./types.js"
/** @type {Types.MyType} */
const myVar = { name : 'Roy', description : 'abc123'};
avantaje:
- mult mai „curat” - mai puțin cod de scris
- trebuie importat doar o dată
dezavantaje:
- puțin improvizat
- nu este idiomatic
- s-ar putea să primești eroarea:
Această importare nu este niciodată folosită ca valoare și trebuie să folosească 'import type' deoarece 'importsNotUsedAsValues' este setat la 'error'
Dacă ai drapelul acela aprins.
Pentru a ocoli acel avertisment, trebuie doar să îl dezactivezi cu un ts-ignore:
// @ts-ignore
import * as Types from "./types.js";
Răspunsul #3
Typescript 5.5 a introdus sintaxa @import. Astfel, poți folosi sintaxa de tip ESM în JSdoc așa cum ai face în Typescript.
Din exemplul tău, devine:
const persons = require('./File1.js');
/** @import { MyObject1 } from './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;

