Search code examples
jsdoctype-variables

JSDoc, type variables


Can we have type variables in JSDoc? For example I want to define identity function:

/**
 * @param {a} x
 * @return {a}
 */
const id = x => x;

But when I use it with concrete types id(2), editor always complains that type number is not assignable to type a. I understand why, as in Haskell or other similar languages the lower cased names in annotation is treat as type variable, but JS views it as concert type. So is there a way to define type variables in JSDoc?

PS: Yea, I know that there is TS and Flow, and I should use them in stead of playing with annotations, but the project I'm working on now is not ready to be migrated to TS, but in same time I want to make things as safe as possible using JS only.


Solution

  • I think you're asking for a type definition for a method where the @param type is always the same as the @return type?

    Borrowing from the Closure Compiler's Wiki: Declaring a bounded generic type:

     /**
      * @param {A} x
      * @template A
      * @return {A}
      */
     const id = (x) => x;
    
     /** @type {string} */
     let str='';
    
     /** @type {number} */
     let num=1;
    
     str=id(true); // Type warning.
    
     str=id('string'); // Type safe.
    
     str=id(1234); // Type warning.
    
     num=id(true); // Type warning.
    
     num=id('string'); // Type warning.
    
     num=id(1234); // Type safe.
    

    Produces the following warnings:

    JSC_TYPE_MISMATCH: assignment
    found   : boolean
    required: string at line 16 character 0
    str=id(true)
    ^
    JSC_TYPE_MISMATCH: assignment
    found   : number
    required: string at line 20 character 0
    str=id(1234)
    ^
    JSC_TYPE_MISMATCH: assignment
    found   : boolean
    required: number at line 22 character 0
    num=id(true)
    ^
    JSC_TYPE_MISMATCH: assignment
    found   : string
    required: number at line 24 character 0
    num=id('string')