Bru*_*oLM 5 generics typescript
我想将类型的元素添加any到数组中,然后从此数组中获取数字的元素:
function OfType<T, U>(list: T[]) : U[]
{
var result: U[] = [];
list.forEach(e => {
// I want to check if e is of type U
//if (typeof(e) === typeof(U)) // ERROR: doesn't work
result.push(<U><any>e);
});
return <any[]>result;
}
var list: any[] = [];
list.push("A");
list.push(2);
var result = OfType<any, number>(list);
alert(result.toString());
Run Code Online (Sandbox Code Playgroud)
但是它不允许我根据泛型类型检查元素的类型.
有没有办法实现这个目标?
小智 17
目前,您可以通过这种方式做得更好(TypeScript 3.9):
// tslint:disable-next-line: no-any
type Constructor<T> = new (...args: any[]) => T;
export function ofType<TElements, TFilter extends TElements>(
array: TElements[],
filterType: Constructor<TFilter>
): TFilter[] {
return <TFilter[]>array.filter(e => e instanceof filterType);
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
class ClassA { }
class ClassB { }
const list: ClassA[] = [new ClassA(), new ClassB()];
const filteredList = ofType(list, ClassB);
Run Code Online (Sandbox Code Playgroud)
正如Judah指出的那样,单独使用泛型类型是不可能的。我找到了一种解决方法,我可以再发送一个参数,其类型为...
function OfType<T, U>(list: T[], arg: Function) : U[]
{
var result: U[] = [];
list.forEach(e => {
// extract the name of the class
// used to match primitive types
var typeName = /function\s*([^(]*)/i.exec(arg+"")[1].toLocaleLowerCase();
var isOfType = typeof(e) === typeName;
// if it is not primitive or didn't match the type
// try to check if it is an instanceof
if (!isOfType)
{
try {
isOfType = (e instanceof arg)
}
catch (ex) { }
}
if (isOfType)
result.push(<U><any>e);
});
return <any[]>result;
}
Run Code Online (Sandbox Code Playgroud)
用法:
var numbers = OfType<any, number>(list, Number);
var foos = OfType<any, Foo>(list, Foo);
alert("Numbers: " + numbers);
alert("Foos: " + foos);
Run Code Online (Sandbox Code Playgroud)
冗余很少,如果有人知道消除这种冗余的方法,请发表评论或编辑此代码。
或者,对于原始类型,只有我可以使用filterJudah 提到的。