打字稿:如何从返回函数的输入参数推断高阶函数中的泛型类型

Typescript: How to infer a generic type in a higher order function from the input parameter of the returned function

type FindCallback<T> = (value: T) => boolean;

type FindResult<T> = (arr: T[]) => T | undefined;

type FindFn = <T>(callback: FindCallback<T>) => FindResult<T>;

const find: FindFn = (callback) => {
    return (arr) => {
        for (let idx = 0; idx < arr.length; idx++) {
            if (callback(arr[idx])) {
                return arr[idx];
            }
        }
        return undefined;
    };
};

const myArray = [1, 5, 4, 9];
const result0 = find<number>((value) => value > 1)(myArray); // works, but explicitly defined the type 'number' in find<number>
const result1 = find((value: number) => value > 1)(myArray); // works, but explicitly defined the type 'number' in the callback (value: number)
const result2 = find((value) => value > 1)(myArray);         // my desired way of calling find(), but the callback parameter 'value' and 'result2' are both 'unknown'
//                              ^
//                      Object is of type 'unknown'.

我正在努力提高我对 Typescript 和函数式编程的理解,并偶然发现了以下场景:

我有一个高阶 find 函数,它应该在数组中找到满足特定条件的第一个元素。

我现在的问题是:

是否可以改进我的类型,以便可以从 myArray 中的值类型推断出我在 FindCallback 中使用的通用类型 T,而无需将其明确定义为 [=14] =]?此外,find()() 的返回值应与数组中的元素具有相同的类型,如果未找到元素,则返回 undefined

这是 link 到 TS Playground

如果这是一个有两个参数的函数:callbackarray 那么它会很简单。实际上,您有两个独立的功能。您无法根据传递给第二个函数的参数推断第一个函数的类型。

这种高阶函数结构意味着不需要立即调用返回的FindResult函数。 const mapper = find((value) => true) 的类型是什么?这是一个在 array of ... 上调用的函数?没有注解value,你根本不知道它最终会用什么类型的数组来调用。

只有当数组是函数的参数时,才可以基于数组类型进行推断。

type FindFn = <T>(callback: FindCallback<T>, arr: T[]) => T | undefined;

const find: FindFn = (callback, arr) => { ...

Playground Link