假设我有一个联合类型type Foo = Bar | Baz
和一组foos(Array<Foo>
)。有没有办法编写一个过滤函数,它以类型安全的方式从数组中只提取某种类型?
类似以下内容,但请指明T
必须是Foo
的成员。因此,例如onlyFoosOfType(x, Number)
将不会进行类型检查。
class Bar {}
class Baz {}
type Foo = Bar | Baz;
var a: Array<Foo> = [];
function
onlyFoosOfType<T>
( arr : Array<Foo>
, ctor : new(...args) => T
): Array<T> {
return <Array<T>> arr.filter(x => {
return x instanceof ctor;
});
}
答案 0 :(得分:1)
以下是一个完整的示例,它接受Bar
或Baz
,但拒绝我创建的其他类作为示例。
突出点是泛型类型约束:T extends Foo
。
TypeScript非常棒,可以接受联合类型,但不能接受其他类型...当然,如果它们在结构上完全相同(即,如果我创建了另一个看起来与Bar
类完全相同的类或者类似于Baz
类,这是允许的。这是有道理的,因为它也允许我在Array<Foo>
中使用该类型。
class Bar {
constructor(public num: number){}
}
class Baz {
constructor(public num: number){}
}
class Example {
}
type Foo = Bar | Baz;
var a: Array<Foo> = [
new Bar(1),
new Baz(2),
new Bar(3),
new Bar(4)
];
function onlyFoosOfType<T extends Foo>(arr : Array<Foo>, ctor : new(...args) => T): Array<T> {
return <Array<T>><any> arr.filter(x => {
return x instanceof ctor;
});
}
var example1 = onlyFoosOfType(a, Bar);
// "[{"num":1},{"num":3},{"num":4}]"
console.log(JSON.stringify(example1));
var example2 = onlyFoosOfType(a, Baz);
// "[{"num":2}"
console.log(JSON.stringify(example2));
// Error: Example is not a Foo!
var example3 = onlyFoosOfType(a, Example);
为了证明这一点,这里是一个可以使用Example
类的版本......
class Bar {
constructor(public num: number){}
}
class Baz {
constructor(public num: number){}
}
class Example {
constructor(public num: number){}
}
type Foo = Bar | Baz;
var a: Array<Foo> = [
new Bar(1),
new Baz(2),
new Bar(3),
new Bar(4),
new Example(5)
];
var example4 = onlyFoosOfType(a, Example);
// "[{"num":5}"
console.log(JSON.stringify(example4));