简体   繁体   English

在Typescript中的通用转换

[英]Generic casting in Typescript

I'm trying to create a simple generic find function in TypeScript, along the lines of: 我正在尝试在TypeScript中创建一个简单的通用查找函数,其行如下:

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, ie if no selector is provided, just return the whole value, ie something like: 我想要做的是提供一个默认选择器,即如果没有提供选择器,只返回整个值,即:

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

However this, (or even (x) => <U>x ) breaks the generic definition of the function. 然而,这()或(甚至(x) => <U>x )打破了函数的通用定义。 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);

ie return the first even number, it infers the type of y as {} ie object instead of number. 即返回第一个偶数,它将y的类型推断为{}object而不是数字。 It seems that, as U can only be inferred from the selector parameter, which is undefined in this case, U defaults to object . 看起来,因为U只能从selector参数中推断出来,在这种情况下未定义,U默认为object I know I ask a bit too much of the type inference, but is there any way around this? 我知道我对类型推断有点过分了,但有什么方法可以解决这个问题吗?

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> 原因<U><any> :类型T可以断言键入U 只有当T为U或U的子类型T的子类型自认为是无法确定你需要转换为<any> 之前,你可以断言到<U>

由于U不一定是T ,因此您需要使用any来更改类型断言以减少特定:

selector = x => <any>x;

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 {
       // ....
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM