Enum as @param type in JSDoc
Asked Answered
F

5

78

Is it possible to use an enum for the JSDoc @param type declaration like in the following example?

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

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

If I use an IDE like Eclipse etc. for JavaScript, there should no warning be raised?

Forestation answered 11/2, 2014 at 13:0 Comment(2)
Did you try? What happened?Mimas
Yes, but only in jsfiddle. It works, also if I use TYPESSS for @param.Forestation
P
132

You can achieve that, by doing this:

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

}

enter image description here

Paisley answered 29/7, 2019 at 14:17 Comment(11)
Thank you very much, this was what I was looking for and should be the accepted answerAnorexia
I couldn't tell you how you made my day, Leuan!Paisley
Could that be combined with @typedef ?Direct
@jakubiszon, yes. Just replace (1|2) with your custom typePaisley
@AhmedMahmoud could I see an example of this? VSCode doesn't seem to pick it up when I do /** @typedef {(1|2)} testEnum */ When I reference it, it understands the type is testEnum but it doesn't suggest the values.Direct
It works for me: imgur.com/a/yz9MHk7. Let me know if you tried the same and didn't work for you.Paisley
for me this worked: @param {'choice1'|'choice2'} typeDonaghue
What if, at some point, the underlying enumeration changes?Gapes
+1 for @DavideVitali 's comment. This is not great practice as we are now repeating ourselves. defining the same type in both the enum and then again in the function param. One has no ties back to the otherRobinetta
Great answer! but how about boolean? can you auto-complete a boolean value using this method? or do i have to do something else?Inbreathe
Hey @Layhout, you can just define it as a boolean after @ param, what's shown above is just because it's a custom type not a basic one.Paisley
I
70

So it seems this is the right way to document everything without any warning

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


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

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

}

This means:

  • MyType is a number
  • TYPES is an enum that holds MyType values
  • This function accepts enums that output MyType values

Works for me on intellij 2017.1

However - this will still allow each string to be passed to the function without warnings.

If you want to specify the enum values too - so it should raise errors if another string was used, use the method described at: https://mcmap.net/q/263309/-how-to-use-jsdoc3-to-document-enum-constants

 /**
    * @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"
    */
Incorporated answered 5/5, 2017 at 18:36 Comment(2)
This solution results in MyType being number. This will ensure that you're sending something that is the same type as the enum's values, but it won't raise errors if you pass unknown values. useTypesEnum( 3 ) would not raise an error here, but should.Hollister
This does not restrict the possible valuesShier
C
14

I use the following:

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

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

This shows the correct values as a suggestion in VSCode. It is nicely readable, gives developers a clue about which value represents what and the enum values can be used in runtime.

Suggestion screenshot


If I do not need the values of TYPES in runtime, I even prefer to use the TYPES as a @typedef:

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

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

If the value of the enum should be used, or the enum keys and values must be flipped for any reason, I use the valueOf<T> helper. The downside is, that this does not offer auto-completion in VSCode. But at least the functions parameter definition is, to some extent, readable.

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

Cupboard answered 2/12, 2022 at 13:3 Comment(3)
The most useful and type-safe answer that is up-to-date. If values require stricter matching, supposed object enum can be type cast to readonly via /** @type {const} */ ({ 0: "TYPE_A", 1: "TYPE_B" }), but yeah it's too verbose.Yangyangtze
It also works if TYPES is a module, imported as import * as someEnum from ''some-enum.js'.Palikar
This is typescript, not pure jsdocShier
B
5

Unfortunately, the only way I found is to define another 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) {
  // ...
}
Boeotian answered 17/6, 2022 at 11:47 Comment(1)
This is cumbersome, but it's also the only way I found (I came here looking for a better way, unfortunately none so far)Shier
S
-8

JSDoc comments have no impact on JavaScript code. What it does influence is some tools designed to use that information. Two of the tools that work with JSDoc comments are the documentation generator and the Google Closure Compiler.

I am not particularly familiar with JSDoc 3, in which the @enum tag has been added, but I would assume it works just as any other type.

The Closure Compiler also recognizes the enum correctly and you can use it just like you mentioned in the example and get all the benefits of the compiler (ex: type checking).

Stavros answered 11/2, 2014 at 13:31 Comment(2)
no, it doesnt create links to that enum, only to typedefs.Westerfield
I don't see how the requestor inferred that the comments would impact the code, instead, they wanted to know how to influence their IDE's type hint logic. What they seem to have requested was whether identifying enums in jsdoc was possible, and if so, what the syntax was, which your answer does not seem to help with. I will admit that their question could have been stated better though.Teem

© 2022 - 2024 — McMap. All rights reserved.