網站搜尋

javascript - 如何在 VS Code 中使用 JSDoc 將 typedef 從一個檔案「匯入」到另一個檔案?


假設我有一個名為 "File1.js" 的檔案。在這個檔案中,我導出了一個物件的物件,並且給每個物件指定了一個類型定義,就像這樣。

/**
 * 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
  }
}

現在,在一個名為「File2.js」的檔案中,我在建構函式中引用這個物件並將其設置為新的 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;

我使用 Visual Studio Code 進行開發,所以按下 Ctrl+Space 我就能得到 IntelliSense。在 file one 中,當我建立 person 物件時,IntelliSense 告訴我 username 是字串,realname 是字串,isUnique 是布林值。但是,當我進入 file2 並透過 this.person 參考新建立的 person 時,當輸入 this.person.username,卻沒有出現預期的 "Username: String" 結果。

在原生 Node.js 中可以在 File2 使用 typedef MyObject1 嗎,還是我沒有希望了?

編輯:有了一些更多的信息後,我能夠找到關於 TypeScript 的 @export 和 @import 的答案,以及我也嘗試過的某種標籤。但這些都沒有用。我還嘗試將 File1.js 標記為 @module,並使用 module:mymodule~MyMethod,但每次這樣做,它都只是將 this.person 標記為 NodeModule,而不是方法本身。

答案#1

使用函數 import 在你的檔案 File2.js 中導入已宣告的類型。

const persons = require('./File1.js');

/**
 * @typedef {import('./File1.js').MyObject1} MyObject1
 */

class File2 {
...

對我來說可行。

答案#2

我在工作中發現的另一件事是導出一個空模型,然後將其用作類型的參考:

types.js:

/** 
* @typedef MyType 
* @prop {string} name  
* @prop {string} description 
*/

export const Types = {}

然後在你的其他檔案中,你可以匯入那個並使用那個虛擬物件的類型:

檔案1.js

import * as Types from "./types.js"

/** @type {Types.MyType} */
const myVar = { name : 'Roy', description : 'abc123'};

優點:

  • 更加“乾淨”——需要寫的程式碼更少
  • 只需要導入一次

缺點:

  • 有點隨便
  • 不地道
  • 你可能會遇到錯誤:

此匯入從未作為值使用,且必須使用 'import type',因為 'importsNotUsedAsValues' 已設定為 'error'

如果你掛著那面旗子。

要繞過那個警告,你只需要用 ts-ignore 將它禁用:

// @ts-ignore  
import * as Types from "./types.js";

答案#3

Typescript 5.5 引入了 @import 語法。所以你可以像在 Typescript 中那樣,在 JSdoc 中使用類似 ESM 的語法。

從你的例子來看,它變成了:

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;