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
函数,它应该在数组中找到满足特定条件的第一个元素。
我现在的问题如下:
是否可以改进我的类型,以便可以从 T
中的值类型推断出我在 FindCallback 中使用的泛型类型 myArray
,而无需将其明确定义为 number
?此外,find()()
的返回值应该与数组中的元素具有相同的类型,或者 undefined
(如果没有找到元素)。
这是 TS Playground 的链接。
答案 0 :(得分:2)
如果这是一个带有两个参数的函数:callback
和 array
那么它会很简单。实际上,您有两个独立的功能。您无法根据传递给第二个函数的参数推断第一个函数的类型。
这种高阶函数结构意味着不需要立即调用返回的FindResult
函数。 const mapper = find((value) => true)
的类型是什么?这是一个在 array
的 ...?如果不注释 value
,您根本无法知道最终将使用什么类型的数组调用它。
只有当数组是函数的参数时,才能根据数组的类型进行推断。
type FindFn = <T>(callback: FindCallback<T>, arr: T[]) => T | undefined;
const find: FindFn = (callback, arr) => { ...