过滤泛型类型

时间:2017-12-04 15:51:44

标签: typescript generics

我正在尝试使用TypeScript编写一个函数,它允许我根据类型过滤对象列表。结果应该是一个允许我这样做的函数:

filter<Foo>(items);

filter(items, Foo);

我一直试图通过以下方式实现:

class Foo {
    public constructor(public name: string, public type: string) {

    }
}

class Bar extends Foo { }

const items: Foo[] = [
    new Foo('Foo', 'A'),
    new Bar('bar', 'A'),
    new Foo('baz', 'B'),
];

const filter = <T extends Foo>(items: any[], typeT: T): T[] => {
    return items.filter(item => item instanceof typeT)
};

console.log(filter(items, Foo));

但这不起作用。

我该如何做到这一点?

TypeScript example

2 个答案:

答案 0 :(得分:2)

当您传入实际传入类的构造函数的类型时。您的签名正在传递T的实例。你应该试试:

const filter = <T extends Foo>(items: any[], typeT: new (...params : any[]) => T): T[] => {
    return items.filter(item => item instanceof typeT)
};

注意:在您的示例中,数组中的所有项都将通过过滤器,因为Bar派生自Foo,因此也是{{1}的实例}}。如果您只想要Foo类型的对象而不是派生,则可以使用Foo

答案 1 :(得分:0)

您可以使用类的name属性简化操作:

class Foo {
    public constructor(public name: string, public type: string) {

    }
}

class Bar extends Foo { }

const items: Foo[] = [
    new Foo('Foo', 'A'),
    new Bar('bar', 'A'),
    new Foo('baz', 'B'),
];

const filter = (items: Foo[], typeT: Function): Foo[] => {
    return items.filter(item => item.constructor.name === typeT.name)
};

console.log(filter(items, Foo)); // Array [ {…}, {…} ]