Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
395 views
in Technique[技术] by (71.8m points)

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'.

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.

question from:https://stackoverflow.com/questions/65946191/typescript-how-to-infer-a-generic-type-in-a-higher-order-function-from-the-inpu

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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) => { ...

Playground Link


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...