Общая проблема заключается в том, что TypeScript плохо работает с универсальными функциями более высокого порядка: https://github.com/Microsoft/TypeScript/issues/9366.
В большинстве случаев, когда вы передаете универсальную функцию (например, R.take(n)
или R.head
) в другую (например, R.pipe
), вместо сохранения свободных параметров универсального типа, TypeScript автоматически выводит их. Большую часть времени он выводит эти параметры как {}
, его пустой тип.
Во втором примере с R.head
выводится строка, потому что R.head
фактически определяется двумя перегрузками:
// from ramda/index.d.ts
head<T>(list: ReadonlyArray<T>): T | undefined;
head(list: string): string;
и поскольку TypeScript еще не может решить, какую перегрузку использовать (вы не указали ни строку, ни массив), он просто выбирает ее. По моему опыту, он выбирает последний, более подробно об этом здесь: https://github.com/Microsoft/TypeScript/issues/13570
Чтобы заставить ваши экземпляры работать, вам нужно вручную заполнить общие параметры, чтобы TypeScript прекратил делать неправильные догадки:
let f4 = R.pipe<number[], number, number>( R.head, f1 );
Для вашего примера с R.take(n)
, согласно Рамде, он на самом деле не должен работать, даже если он напечатал, так как возвращает массив, а не единственное значение:
// from ramda/index.d.ts
take<T>(n: number): {
(xs: string): string;
(xs: ReadonlyArray<T>): T[];
};