【问题标题】:jsdoc : reference typedef-ed type from other modulejsdoc:从其他模块引用 typedef-ed 类型
【发布时间】:2017-08-07 08:13:03
【问题描述】:

假设我在 js 模块中有一个 typedef 类型

// somewhere/foo.js
/**
 * @module
 */ 
/**
 * @typedef Foo
 * @type {object}
 * property {string} bar - some property
 */

是否可以在另一个模块中引用该类型,以便在jsdoc生成的HTML页面中,将该类型显示为指向typedef-ed模块的链接?

我尝试了这个的变体,但似乎没有任何效果......

// somewhere_else/bar.js
/**
 * @module
 */
/**
 * @param {somewhere/foo/Foo} foo - some param
 */
export default function doStuff(foo) {
  ...
}

【问题讨论】:

    标签: jsdoc jsdoc3


    【解决方案1】:

    这对我有用...

    // somewhere/foo.js
    /**
     * @module foo
     */
    /**
     * @typedef module:foo.Foo
     * @type {object}
     * @property {string} bar - some property
     */
    

    和...

    // somewhere_else/bar.js
    /// <reference path="foo.js" />
    /**
     * @module bar
     */
    /**
     * @param {module:foo.Foo} foo - some param
     */
    function doStuff(foo) {
      //...
    };
    

    【讨论】:

    • 完全限定 @typedef 中的模块确实有效(我个人写了 @typedef {Object} module:foo/Foo ,但这是一个品味问题。)但是:1 / /// &lt;reference path="foo.js" /&gt; 似乎不需要,我可以找不到它记录在任何地方。 2/如果模块有很长的路径(比如'somewhere/foo')在任何地方输入它有点乏味,你知道以某种方式给它取别名的任何技巧吗?
    • @phtrivier 1. 对不起,参考只是我测试的复制和粘贴,忽略它。 2.完全同意你的观点,有点乏味;不幸的是,“别名”是我们记录的方式(特别是原型)。事实上,它看起来并没有那么糟糕。我看到了它的好处:使用此方法或类型的开发人员将确切地知道它在哪里定义,因此它不仅有助于创建正确的文档,而且在开发过程中寻找有效的参考。还有另一种使用“@exports”的方式,但我没有发现这个选项,所以无法评论。
    【解决方案2】:

    上述答案在搜索结果中的排名很高,因此我正在记录对我有用的方法,以防它对处于类似情况的人有所帮助。

    我在我的所有模块上都使用 // @ts-check 的节点项目的 Visual Studio 代码。在module: 语法上使用上述语法会出现问题。此外,代码帮助无法正常工作。我花了一段时间,但最终答案很简单

    如果我在模块myModule 中有typedef myTypedef,那么在我需要myModule 的第二个模块中
    mm = require(myModule)
    我可以使用类似
    /** @param {mm.myTypedef} myParamName */

    【讨论】:

      【解决方案3】:

      以上两种方法我都试过了。

      首先,在@typedef module:foo.Foo 的情况下,VSCode 将 Foo 的用法与any 处理在同一文件中。我觉得不能接受。

      其次,使用 ES6 导入时会出现以下问题:

      import foo from 'foo'
      
      /** @param {foo.Foo} a - Error Foo does not exist on foo */ 
      

      另一方面,VSCode 识别import { Foo } from 'foo' 无需,即使使用 JSDoc 模块语法:

      /**
       * @module bar
       */
      

      此外,我还能够引用导入类型的属性,即:

      import { Foo } from 'foo'
      
      /** @param {Foo['bar']} bar */
      
      

      注意

      本项目使用 Babel 并假设在没有转译器的情况下编译使用类型导入的代码是不可行的。

      【讨论】:

        【解决方案4】:

        许多库从其根文件导出类型,要访问 typedef 中的类型,请将导入更改为使用 import * as 格式。

        例如:

        import * as testingLibrary from '@testing-library/react';
        
        
        /** 
         * @returns {testingLibrary.RenderResult}
         */
        export function myCustomRender() { }
        
        

        【讨论】:

          【解决方案5】:

          我正在使用vscode-powertools 脚本,该脚本提供对vscode 模块在运行时 的访问(而不是在编辑时通过本地node_modules 提供给VSCode)。

          如果我尝试使用通常的 jsdoc import 导入类型

          //@ts-check
          /** @typedef {import('c:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode').TextEditor} TextEditor */
          

          我会收到File is not a module 错误:

          File 'C:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode/vscode.d.ts' is not a module. ts(2306)
          

          所以这是我用来检查那种脚本的技巧:

          //@ts-check
          /// <reference types="c:/Users/USERNAME/.vscode/extensions/ego-digital.vscode-powertools-0.64.0/node_modules/vscode" /> 
          
          // Allows us to reference the `vscode` module with jsdoc `@type`
          async function vscodeⁱ() {if (1 == 1) return null; return import ('vscode')}
          
          exports.execute = async (args) => {
            // Allows us to reference the `vscode` module with jsdoc `@type`
            const vscode = await vscodeⁱ()
          
            /** @type {vscode} */
            const vs = args.require ('vscode')
          
            // NB: The following code is fully typed in VSCode
            const windowᵛ = vs.window
            const editorᵛ = windowᵛ.activeTextEditor
            const start = editorᵛ.selection.start
          }
          

          【讨论】:

            【解决方案6】:

            TypeScript 不支持 module 语法,因此如果您假设它可以工作,那么我无法让上述解决方案正常工作。

            要使其与 TypeScript 一起使用,请使用 Import Types

            对于 OP,我会这样做

            // foo.d.ts
            export type Foo = {
              /**
               * some property
               */
              bar: string,
            };
            

            然后在JS模块中引用为

            /**
             * @typedef { import("./foo").Foo } Foo
             */
            
            /**
             * @param {Foo} foo - some param
             */
            export default function doStuff(foo) {
              ...
            }
            

            您可以通过将以下内容添加到文件的开头来更严格地验证单个文件是否正在运行。这将启用特定文件的 Visual Studio 代码中的 typescript 检查,以帮助您为将来迁移到 Typescript 做好准备。

            // @ts-check
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-01-06
              • 1970-01-01
              • 2018-07-15
              • 2017-07-24
              • 1970-01-01
              • 2015-04-23
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多