Функция TypeScript «not»

#typescript #generics #types #functional-programming #typescript-generics

#typescript #дженерики #типы #функциональное программирование #typescript-дженерики

Вопрос:

Как мне указать TypeScript подключить тип параметра fn выше к типу параметра ...args ниже??

   /**
   * @template F
   * @param {(...o: Parameters<F>) => boolean} fn
   */
  function not(fn) {
    return (
      /**
       * @param {Parameters<F>} args
       * @returns {boolean}
       */
      (...args) => {
        return !fn(...args);
      }
    );
  }
 

Ответ №1:

Поскольку вы используете JSDoc, я думаю, я бы написал это так:

 /**
 * @template {any[]} A
 * @param {(...args: A)=>boolean} fn
 */
function not(fn) {
  return (
    /**
     * @param {A} args
     * @returns {boolean}
     */
    (...args) => {
      return !fn(...args);
    });
}
 

Дело в том, чтобы быть универсальным в A , тип args вместо в F котором предположительно является типом функции.

Вы можете протестировать ее:

 /**
 * @param {string} x
 * @param {number} y
 */
function hmm(x, y) {
  return x.length === y;
}

const notHmm = not(hmm);
notHmm("", 2)
notHmm(123, "") // error!
// --> ~~~
// Argument of type 'number' is not assignable to parameter of type 'string'.(2345)
notHmm(); // error!
// Expected 2 arguments, but got 0.(2554)
 

Выглядит хорошо.

Игровая площадка ссылка на код

В TS это было бы

 function not<A extends any[]>(
  fn: (...args: A) => boolean
) {
  return (
    (...args: A) => {
      return !fn(...args);
    });
}
 

Ссылка на игровую площадку для кода

Комментарии:

1. Я не хочу использовать any , я пытаюсь позволить TypeScript убедиться, что моя обернутая функция имеет те же типы параметров, что и функция, которую она переносит.

2. Да, это то, что делает этот ответ. Вы не «используете any » в том смысле, о котором вы могли бы подумать.

3. О, я вижу, что вы сделали, вы просто расширили any[] . Ну, это в основном работает, за исключением того, что TypeScript сообщает мне, что аргумент теперь необязательный. Итак, если f принимает string, number , not(f) принимает string?, number?

4. Именно так работает JS с проверкой TS . Не уверен, что вы хотите, чтобы я с этим поделал. На самом деле, я не могу воспроизвести это , поэтому вы можете уточнить свою проблему (хотя, если это просто то, как работает JS-in-TS, я не могу ничего сделать, кроме как посочувствовать вам)

5. Оказывается, необязательная вещь заключалась в том, что я использовал @type прямо перед параметром, а @param не прямо перед функцией, которая исправляет ошибку-необязательность. Итак, ваш ответ просто великолепен.