假设我有一个名为“File1.js”的文件。在这个文件中,我导出一个对象的对象,并给每个对象一个 typedef,就像这样。
/**
* 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。在文件一中,当我创建 person 对象时,IntelliSense 告诉我 username 是一个字符串,realname 是一个字符串,isUnique 是一个布尔值。但是,当我进入 file2 并通过
this.person
引用新创建的人时,输入 this.person.username
时,它不会出现“用户名:字符串”的预期结果。
是否可以在普通 Node.js 的 File2 中使用 typedef
MyObject1
,还是我运气不好?
编辑:有了更多信息,我能够找到 TypeScript 的 @export 和 @import 的答案,以及我也尝试过的各种标签。所有这一切都无济于事。我还尝试将 File1.js 标记为 @module,并执行
module:mymodule~MyMethod
,但每次我这样做时,它只是将 this.person 标记为 NodeModule,而不是方法本身。
我发现有用的另一件事是导出并清空模型,然后将其用作类型的引用:
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'};
优点:
缺点:
此导入从不用作值,必须使用“导入类型” 因为“importsNotUsedAsValues”设置为“错误”
如果你有那个标志。
要绕过该警告,您只需使用 ts-ignore 禁用它:
// @ts-ignore
import * as Types from "./types.js";
这是我发现的最干净的方法。我已经验证它可以在 VSCode 中用于自动完成/智能感知并在悬停时显示信息。 TypeScript 引擎还应该能够从中推断出所有类型信息。
首先,我在根目录中创建一个名为
api-type-definitions.js
的文件。我将展平所有嵌套的对象/方法/函数,以便每个对象/方法/函数都有自己的命名类型定义。然后他们可以根据需要互相参考。然后我创建一个实际的 JavaScript 变量并为其分配类型并导出该变量。
/**
* OPTIONAL: console.error is called by default if verbose: true.
*
* @callback {Function} CUSTOMLOGGER
* @param {string} message The human readable warning/error message
* @param {object} [error] Sometimes an error or options object is passed
* @return {void}
*/
/**
* @typedef {object} WINDOWS
* @property {string} filePath The target the shortcut points to.
* @property {string} [outputPath] Path where shortcut will be placed. Defaults to user's desktop.
* @property {string} [windowMode="normal"] How the window should be displayed by default. Valid inputs: 'normal', 'maximized', 'minimized'. Defaults to 'normal'.
*/
/**
* @typedef {object} LINUX
* @property {string} filePath The target the shortcut points to.
* @property {string} [outputPath] Path where shortcut will be placed. Defaults to user's desktop.
* @property {string} [comment] Metadata file "comment" property. Description of what the shortcut would open.
*/
/**
* @typedef {object} OSX
* @property {string} filePath The target the shortcut points to.
* @property {string} [outputPath] Path where shortcut will be placed. Defaults to user's desktop.
* @property {string} [name] Name of the shortcut file.
*/
/**
* @typedef {object} OPTIONS
* @property {CUSTOMLOGGER} [customLogger] Called (if verbose: true) with helpful warning/error messages from internal validators.
* @property {WINDOWS} [windows] Windows shortcut settings.
* @property {LINUX} [linux] Linux shortcut settings.
* @property {OSX} [osx] OSX shortcut settings.
*/
/**
* @type {LINUX}
*/
let LINUX;
/**
* @type {OPTIONS}
*/
let OPTIONS;
module.exports = {
LINUX,
OPTIONS
};
请注意,我仅导出将重用的类型。其余的定义只是为了更容易编写/阅读而扁平化。
然后在我想要使用该类型的任何文件中,导入变量并在 JSDoc 块中将其引用为类型。
const { OPTIONS } = require('./api-type-definitions.js');
/**
* Creates OS based shortcuts for files, folders, urls, and applications.
*
* @param {OPTIONS} options Options object for each OS, and global options
* @return {boolean} True = success, false = failed to create the icon or set its permissions (Linux).
*/
function createDesktopShortcut (options) {
// the library code
}
module.exports = createDesktopShortcut;
示例存储库:
我也强烈推荐
eslint-plugin-jsdoc
,如果你想要一个起点,这里是我的规则:
还有另一种方法。
创建
types.js
/**
* @typedef {object} LINUX
* @property {string} filePath The target the shortcut points to.
* @property {string} [outputPath] Path where shortcut will be placed. Defaults to user's desktop.
* @property {string} [comment] Metadata file "comment" property. Description of what the shortcut would open.
*/
/**
* @typedef {object} OSX
* @property {string} filePath The target the shortcut points to.
* @property {string} [outputPath] Path where shortcut will be placed. Defaults to user's desktop.
* @property {string} [name] Name of the shortcut file.
*/
只需将它们导入您的
file.js
import './types.js'
/** @type {LINUX} */
const Linux = {}