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'.
I'm trying to improve my understanding of Typescript and functional programming and stumbled upon the following scenario:
I have this higher order find
function that is supposed to find the first element within an array that satisfies a certain condition.
My question now is the following:
Is it possible to improve my typings so that the generic type T
that I used in FindCallback can be inferred from the type of the values in myArray
without explicitly defining it as number
? Also the returned value of find()()
should have either the same type as the elements in the array or undefined
if no element was found.
Here's a link to TS Playground.
If this were to be a function with two arguments: callback
and array
then it would be simple. As it is, you have two separate functions. You cannot infer the type of the first function based on the arguments that you pass to the second function.
This higher-order function structure means that the returned FindResult
function does not need to be immediately invoked. What is the type of const mapper = find((value) => true)
? It's a function that gets called on an array
of ...? Without annotating value
, you simply cannot know what type of array it will eventually be called with.
Inference based on the type of the array is only possible when the array is an argument of the function.
type FindFn = <T>(callback: FindCallback<T>, arr: T[]) => T | undefined;
const find: FindFn = (callback, arr) => { ...
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments