Typescript 中的通用转换

Generic casting in Typescript

我正在尝试在 TypeScript 中创建一个简单的通用查找函数,代码如下:

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

所以,我的参数是:
- 要过滤的数组
- 测试每个元素的谓词
- 获取 return 值

的选择器

我想做的是提供一个默认选择器,即如果没有提供选择器,则只 return 整个值,即类似于:

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

然而,这(甚至 (x) => <U>x)打破了函数的通用定义。如何在不删除通用参数的情况下实现默认选择器?


如果我使用如下代码:

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

即return 第一个偶数,它推断 y 的类型为 {}object 而不是数字。 似乎,由于 U 只能从 selector 参数推断,在这种情况下未定义,因此 U 默认为 object。 我知道我对类型推断的要求有点过分了,但是有什么办法可以解决这个问题吗?

由于 U 不一定是 T,您需要使用 any 将类型断言更改为不那么具体:

selector = x => <any>x;

完整代码如下:

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];
}

<U><any> 的原因:如果 T 是 U 的子类型或 U 是T 的子类型。由于无法确定,您需要在 之前转换为 <any> ,您可以断言为 <U>

您可以将默认值移动到参数声明中。

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