Why does TS complain when using @type instead of @param and @return when writing a generic function?
P粉464082061
P粉464082061 2024-04-03 12:10:23
0
1
416

Why TS is complaining about this:

/**
 * @template X
 * @type {function(X): X}
 */
const identity1 = (x) => x;

/**
 * @template X
 * @type {function(X): X}
 */
const identity2 = (x) => identity1(x);

TypeScript Error Message:

Type 'X' is not assignable to type 'X'. Two different types with this name exist, but they are unrelated.
  'X' could be instantiated with an arbitrary type which could be unrelated to 'X'.ts(2719)
graph.mjs(4, 14): This type parameter might need an `extends X` constraint.
const identity1: (arg0: X) => X
@template X
@type — {function(X): X}

However, when changing the @type using @param and @return it works fine:

/**
 * @template X
 * @param {X} x
 * @returns {X}
 */
const identity1 = (x) => x;

/**
 * @template X
 * @type {function(X): X}
 */
const identity2 = (x) => identity1(x);

I do not understand why. The documentation makes no mention of how these two signatures interact differently with generic types.

P粉464082061
P粉464082061

reply all(1)
P粉448130258

Use the @type tag to refer to the type range limited to curly braces. That is, @type {function(X): X} does not refer to the generic type because we referenced X outside the scope. At least that's my interpretation. Regardless, extracting the provided type from @type is not supported.

However, you can use @typedef to override functions:

/**  
* @template X  
* @typedef {X extends number ? [1, 2, 3][X] : never} Successor  
*/ 

/**  
* @template X  
* @typedef {X} Identity  
*/ 

/**
* @template X  
* @typedef {Identity>} Identity2  
*/

/** @type {Successor>} */ 
const x = 2;  

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template