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 {
// ....
}
我正在尝试在 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 {
// ....
}