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;

Relaterte artikler