Неточный вывод типа функций pipe и compose в TypeScript

1
6

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

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

Вопросы:

Использование

function pipe<X, Y, Z>(first: (x: X) => Y): (f2: (y: Y) => Z) => (x: X) => Z {
  return function (second: (y: Y) => Z): (x: X) => Z {
    return function (x: X): Z {
      return second(first(x));
    };
  }
}

function compose2<X, Y, Z>(second: (y: Y) => Z): (f2: (x: X) => Y) => (x: X) => Z {
  return function (first: (x: X) => Y): (x: X) => Z {
    return function (x: X): Z {
      return second(first(x));
    };
  }
}
function numToStr(n: number): string { return n.toString(); }
function strToLen(s: string): number { return s.length; }

// Inferred as (x: number) => unknown
// Should be (x: number) => number
const f1 = pipe(numToStr)(strToLen);

// Inferred as(x: unknown) => number
// Should be (x: number) => number
const f2 = compose(strToLen)(numToStr);
Севастьян
Вопрос задан9 января 2024 г.

1 Ответ

2

Вместо того, чтобы жестко codeировать возвращаемый тип каждой функции. Позвольте TypeScript вывести его и убедитесь, что общие параметры используются не слишком рано:

function pipe<X, Y>(first: (x: X) => Y) { // <-- Avoid <Z> here is too early
  return function <Z>(second: (y: Y) => Z) { // <-- <Z> is needed here
    return function (x: X) {
      return second(first(x));
    };
  }
}

function compose<Y, Z>(second: (y: Y) => Z) {// <-- Avoid <X> here is too early
  return function <X>(first: (x: X) => Y) {// <-- <X> is needed 
    return function (x: X): Z {
      return second(first(x));
    };
  }
}

function numToStr(n: number): string { return n.toString(); }
function strToLen(s: string): number { return s.length; }

const f1 = pipe(numToStr)(strToLen);
const f2 = compose(strToLen)(numToStr);
Сила
Ответ получен11 сентября 2024 г.

Ваш ответ

Загрузить файл.