Generic casting in Typescript

早过忘川 提交于 2019-12-14 01:45:41

问题


I'm trying to create a simple generic find function in TypeScript, along the lines of:

export function findFirst<T, U>(
        array: T[], 
        predicate: (item: T) => boolean, 
        selector?: (item: T) => U): U {
     ...
}

So, my parameters are:
- the array to filter through
- a predicate to test each element
- a selector to get the return value

What I want to do is provide a default selector, i.e. if no selector is provided, just return the whole value, i.e. something like:

if (typeof selector === "undefined")
    selector = (x) => x;

However this, (or even (x) => <U>x) breaks the generic definition of the function. How can I achieve a default selector without removing the generic parameters?


If I use code like:

var arr = [1,2,3,4];
var even = findFirst(arr, x => x % 2 === 0);

i.e. return the first even number, it infers the type of y as {} i.e. object instead of number. It seems that, as U can only be inferred from the selector parameter, which is undefined in this case, U defaults to object. I know I ask a bit too much of the type inference, but is there any way around this?


回答1:


Here is the complete code:

export function findFirst<T, U>(
        array: T[], 
        predicate: (item: T) => boolean, 
        selector: (item: T) => U = (x:T)=> <U><any>x): U {
     return array.filter(predicate).map(selector)[0];
}

Reason for <U><any> : Type T can be asserted to type U only if T is a subtype of U OR U is a subtype of T. Since that is not determinable you need to convert to <any> before you can assert to <U>




回答2:


Since a U isn't necessarily a T, you'd need to change the type assertion to be less specific by using any:

selector = x => <any>x;



回答3:


You can just move the default value to the parameter declaration.

function findFirst<T, U>(
    array: T[], 
    predicate: (item: T) => boolean, 
    selector: (item: T) => U = (x => x)): U {
       // ....
}


来源:https://stackoverflow.com/questions/28299380/generic-casting-in-typescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!