JSDoc中@param类型的枚举

74

在JSDoc的@param类型声明中是否可以像下面的例子一样使用enum?

/**
 * @enum { Number }
 */
const TYPES = {
    TYPE_A: 1,
    TYPE_B: 2
}

/**
 * @param { TYPES } type
 */
function useTypesEnum( type ) {
    
}

如果我像使用Eclipse等IDE来编写JavaScript,那么不应该会出现任何警告吗?


1
你试过了吗?发生了什么事情? - Xotic750
是的,但只在jsfiddle上有效。它也可以工作,即使我使用TYPESSS代替@param - BuZZ-dEE
5个回答

120

通过这样做,您可以实现目标:

/**
* @param {(1|2)} type
*/
function useTypesEnum(type) {

}

这里输入图片描述


4
非常感谢,这正是我所寻找的,应该被认可为答案。 - Ieuan
1
我无法告诉你,Leuan,你是如何让我的一天变得美好的! - Ahmed Mahmoud
能否与 @typedef 结合使用? - jakubiszon
9
对我来说,这个方法起作用了:@param {'choice1'|'choice2'} type。 (注:该方法接受一个名为“type”的参数,可以是字符串“choice1”或“choice2”中的任意一个) - tehmas
1
如果底层枚举在某个时候发生了变化,会怎么样? - Davide Vitali
显示剩余6条评论

67

看起来这是在没有任何警告的情况下记录所有内容的正确方式。

/**
 * @typedef {number} MyType
 **/


/**
 * @enum {MyType}
 */
var TYPES = {
    TYPE_A: 1,
    TYPE_B: 2
}

/**
 * @param {MyType} type
 */
function useTypesEnum( type ) {

}

这意味着:

  • MyType 是一个数字
  • TYPES 是一个枚举,保存 MyType 值
  • 该函数接受输出 MyType 值的枚举

在 intellij 2017.1 上对我有效。

然而 - 这仍将允许每个字符串传递给函数而没有警告。

如果您想指定枚举值,以便如果使用了另一个字符串则应引发错误,请使用以下方法:https://dev59.com/sJXfa4cB1Zd3GeqPlNsQ#36501659

 /**
    * @typedef FieldType
    * @property {string} Text "text"
    * @property {string} Date "date"
    * @property {string} DateTime "datetime"
    * @property {string} Number "number"
    * @property {string} Currency "currency"
    * @property {string} CheckBox "checkbox"
    * @property {string} ComboBox "combobox"
    * @property {string} Dropdownlist "dropdownlist"
    * @property {string} Label "label"
    * @property {string} TextArea "textarea"
    * @property {string} JsonEditor "jsoneditor"
    * @property {string} NoteEditor "noteeditor"
    * @property {string} ScriptEditor "scripteditor"
    * @property {string} SqlEditor "sqleditor"
    */

3
这种解决方案将使 MyType 成为 number。这将确保您发送的内容与枚举值具有相同的类型,但如果您传递未知值,它不会引发错误。在此情况下,useTypesEnum(3) 不会引发错误,但应该会引发错误。 - Mark
这不限制可能的值。 - Lideln Kyoku

12

我使用以下内容:

const TYPES = {
    0: "TYPE_A",
    1: "TYPE_B"
}

/**
 * @param {keyof TYPES} type
 */
function useTypesEnum(type) {
    // ...
}

这在VSCode中显示了正确的值作为建议。它易于阅读,给开发人员提供了哪个值表示什么的线索,并且枚举值可以在运行时使用。

建议截图


如果我不需要在运行时使用TYPES的值,我甚至更喜欢将TYPES用作@typedef

/**
 * @typedef {{ 
 *     0: "TYPE_A",
 *     1: "TYPE_B"
 * }} TYPES
 */

/**
 * @param {keyof TYPES} type
 */
function useTypesEnum(type) {
    // ...
}

如果枚举的应该被使用,或者由于任何原因需要翻转枚举的键和值,则可以使用valueOf<T>助手。缺点是,在VSCode中它不提供自动完成。但至少函数的参数定义在某种程度上是可读的。

/**
 * @typedef {T[keyof T]} valueOf<T>
 * @template T
 */

const TYPES = {
    "TYPE_A": 0,
    "TYPE_B": 1
};

/**
 * @param {valueOf<TYPES>} type
 */
function useTypesEnum(type) {
    // ...
}

Suggestion 2 screenshot


2
最有用且类型安全的答案是最新的。如果值需要更严格的匹配,假设对象枚举可以通过 /** @type {const} */ ({ 0: "TYPE_A", 1: "TYPE_B" }) 进行类型转换为只读,但是这太冗长了。 - vintprox
如果TYPES是一个模块,并以import * as someEnum from ''some-enum.js'导入,这也是可行的。 - Hibou57
这是TypeScript,不是纯粹的JSDoc。 - Lideln Kyoku

4

不幸的是,我找到的唯一方法是定义另一个type@typedef):

/**
 * @enum { number }
 */
const TYPES = {
    TYPE_A: 1,
    TYPE_B: 2
}

/** @typedef {'TYPE_A'|'TYPE_B'} TYPES_KEYS */

/**
 * @param { TYPES_KEYS } input
 */
function useTypesEnum(input) {
  // ...
}

1
这很麻烦,但这也是我找到的唯一方法(我来这里寻找更好的方法,但不幸的是目前还没有)。 - Lideln Kyoku

-7

JSDoc注释对JavaScript代码没有影响。它影响的是一些旨在使用该信息的工具。与JSDoc注释一起使用的两个工具是文档生成器和Google Closure Compiler。

我对JSDoc 3不是特别熟悉,其中添加了@enum标签,但我认为它的工作方式与其他任何类型相同。

Closure Compiler也正确识别了enum,您可以像示例中提到的那样使用它,并获得编译器的所有好处(例如:类型检查)。


不,它不会创建到该枚举的链接,只会创建到typedef的链接。 - xamiro
3
我不明白请求者是如何推断出注释会影响代码的,相反,他们想知道如何影响他们IDE的类型提示逻辑。他们似乎要求的是是否可能在jsdoc中识别枚举,如果可能的话,语法是什么,而您的答案似乎并没有帮助到他们。尽管如此,我承认他们的问题可以表述得更好。 - Jitsusama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接