如何输入咖喱“地图”?

How to type a curried `map`?

我正在尝试在 TypeScript 中键入柯里化 map 函数。这是 JavaScript 等价物:

const double = n => n * 2;
const map = f => arr => arr.map(f);
const doubleArr = map(double);

console.log(doubleArr([1, 2, 3]));
// ↳ [2, 4, 6]

理想情况下,TypeScript 应该能够推断,在将 double 提供给 map 之后,doubleArray 接受一个数字数组,returns 接受一个数字数组.

这是我尝试过的:

const double = (n: number) => n * 2;
const map = (f: Function) => (arr: Array<any>) => arr.map(f);

但是,TypeScript 抱怨 fmap 中:

Argument of type 'Function' is not assignable to parameter of type '(value: any, index: number, array: any[]) => unknown'.
  Type 'Function' provides no match for the signature '(value: any, index: number, array: any[]): unknown'.

你会如何在 TypeScript 中输入这个函数?

您可以创建一个带有两个参数的函数 map:数组和函数,以及何时要使用此函数,您应该将数组中的一个项目提供给此函数。

const double = (n: number) => n * 2;
const map = (arr: Array<any>, f: Function) => arr.map((item: any) => f(item));
map([1, 2, 3], double)

你可以声明一个接口然后传递它而不是Function

interface ArrFunction<T> {
    (n: T): T
}

const double = (n: number) => n * 2;
const map = (f: ArrFunction<any>) => (arr: Array<any>) => arr.map(f);

您可以使用以下声明:

const double = (n: number) => n * 2;
const map = <A, R>(f: (arg: A) => R) => (arr: A[]) => arr.map(f);
const doubleArr = map(double); // (arr: number[]) => number[]

console.log(doubleArr([1, 2, 3]));
// ↳ [2, 4, 6]

Playground sample


解释:ARdouble打字的generic type parameters. map(double) returns a function with signature (arr: number[]) => number[], because TS is able to infer,即AR都只能是number 这里.