javascript - Hvordan "importere" en typedef fra en fil til en annen i JSDoc ved bruk av VS Code?
La oss si jeg har en fil som heter "File1.js". I denne filen eksporterer jeg et objekt av objekter, og jeg gir hvert objekt en typedef, som følger.
/**
* 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
}
}
Nå, i en fil kalt "File2.js", refererer jeg til dette objektet i en konstruktør og setter det til en ny 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;
Jeg bruker Visual Studio Code for utvikling, så ved å trykke Ctrl+Space får jeg IntelliSense. I fil én, mens jeg lager person-objektene, forteller IntelliSense meg at username er en string, realname er en string, og isUnique er en boolean. Men når jeg går inn i fil2 og refererer til den nylig opprettede personen via this.person, når jeg skriver this.person.username, kommer ikke det forventede resultatet "Username: String" opp.
Er det mulig å bruke typedef MyObject1 i File2 i vanlig Node.js, eller er jeg ute av lykken?
Rediger: Med litt mer informasjon klarte jeg å finne svar med @export og @import for TypeScript, samt en slags tag som jeg også prøvde. Alt uten hell. Jeg prøvde også å merke File1.js som en @module, og gjøre module:mymodule~MyMethod, men hver gang jeg gjorde det, markerte det bare this.person som en NodeModule i stedet for selve metoden.
Svar #1
Importer den deklarerte typen i filen din File2.js ved å bruke funksjonen import.
const persons = require('./File1.js');
/**
* @typedef {import('./File1.js').MyObject1} MyObject1
*/
class File2 {
...
Det fungerer for meg.
Svar #2
En annen ting jeg oppdaget mens jeg jobbet, er å eksportere en tom modell og deretter bruke den som en referanse for typene:
types.js:
/**
* @typedef MyType
* @prop {string} name
* @prop {string} description
*/
export const Types = {}
Så i de andre filene dine kan du importere det og ha typene fra det dummy-objektet:
Fil1.js
import * as Types from "./types.js"
/** @type {Types.MyType} */
const myVar = { name : 'Roy', description : 'abc123'};
fordeler:
- mye "renere" - mindre kode å skrive
- må bare importeres én gang
ulemper:
- litt hektisk
- ikke idiomatisk
- du kan få feilen:
Denne importen brukes aldri som en verdi og må bruke 'import type' fordi 'importsNotUsedAsValues' er satt til 'error'
Hvis du har det flagget på.
For å omgå den advarselen trenger du bare å deaktivere den med en ts-ignore:
// @ts-ignore
import * as Types from "./types.js";
Svar #3
Typescript 5.5 introduserte @import-syntaks. Så du kan bruke ESM-lignende syntaks i JSdoc slik du ville gjort i Typescript.
Fra ditt eksempel blir det:
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;

