在Typescript中的通用转换

时间:2015-02-03 12:50:14

标签: generics casting typescript

我正在尝试在TypeScript中创建一个简单的通用查找函数,类似于:

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

所以,我的参数是:
- 要通过
过滤的数组 - 测试每个元素的谓词
- 获取返回值的选择器

我想要做的是提供默认选择器,即如果没有提供选择器,只返回整个值,即:

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

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


如果我使用以下代码:

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

即。返回第一个偶数,它将y的类型推断为{},即object而不是数字。 看起来,因为U只能从selector参数中推断出来,在这种情况下未定义,U默认为object。 我知道我对类型推断有点过分,但有什么方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

以下是完整的代码:

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的子类型,则T类型U可以断言为<any> ,而U是U的子类型。由于这是不可确定的,您需要在之前转换为<U> ,您可以断言为{{1}}

答案 1 :(得分:2)

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

selector = x => <any>x;

答案 2 :(得分:1)

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

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