How to use @template in function JSDoc to create coherence between param and return type?

Viewed 357

I use @ts-check and ts linter on an ecmascript projet (I cannot use typescript but want its formalism).

All is going well except for one thing: I want to use JSDoc generics declaration so that return type is tied-to/inferred-from a parameter type:

/**
 * @template V - Type de valeurs de la map.
 * @param {Map<string, V>} map
 * @returns {Object.<string, V>}
 */
function objectifyMap(map) {
    /** @type {Object.<string,V>} */
    const result = {};
    map.forEach((value, key) => { result[key] = value; });
    return result;
}

/**
 * @template V
 * @param {Object.<string, V>} object
 * @returns {Map<string, V>}
 */
function mappifyObject(object) {
    /** @type {Map<string,V>} */
    const result = new Map();
    Object.entries(object).forEach(([key, value]) => { result.set(key, value); });
    return result;
}

/** @type {Object.<string, string>} */
const obj = {};

/** @type {Map<string, string>} */
let map;
map = mappifyObject(obj);

But on the last line, ts linter throws an error on obj parameter:

Argument of type '{ [x: string]: string; }' is not assignable to parameter of type '{ [x: string]: V; }'.
  Index signatures are incompatible.
    Type 'string' is not assignable to type 'V'.
      'V' could be instantiated with an arbitrary type which could be unrelated to 'string'.ts(2345)

I guess ts linter is expecting map = mappifyObject<string>(obj); but as I'm only using @ts-check and not the typescript transpiler, I cannot do that.

Does anyone knows how to circumvent that?

0 Answers
Related