如何将instanceof与泛型函数类型一起使用

时间:2020-05-03 19:18:06

标签: typescript

在下面的示例中,我想确保返回的类型与泛型函数中给定的泛型类型相对应。 不幸的是,在使用result instanceof T时,TypeScript报告以下错误:error TS2693: 'T' only refers to a type, but is being used as a value here。 有没有一种方法可以在运行时检查对象的类型是否对应于泛型?

class Foo {
    id: number;
    constructor(id: number) {
        this.id = id;
    }
}

class Bar extends Foo {
    name: string;
    constructor(id: number, name: string) {
        super(id);
        this.name = name;
    }
}

function get<T>(list: Array<Foo>, id: number): T|undefined {
    const result = list.find(e => e.id === id);
    if (typeof result === 'undefined') {
        return undefined;
    }

    if (!(result instanceof T)) { // error TS2693: 'T' only refers to a type, but is being used as a value here 
        return undefined;
    }

    return result as unknown as T;
}

const foos = [new Foo(1), new Bar(2, 'bar'), new Foo(3)];

console.log(get<Foo>(foos, 1));
console.log(get<Foo>(foos, 2));
console.log(get<Bar>(foos, 3));

1 个答案:

答案 0 :(得分:1)

类型(和类型参数)在编译期间被删除,因此您不能说result instanceof T,因为在运行时没有T

您可以做的是将类本身传递给函数(它是一个值,因此可以在运行时使用)


function get<T>(cls: new (...a: any) => T, list: Array<Foo>, id: number): T|undefined {
    const result = list.find(e => e.id === id);
    if (typeof result === 'undefined') {
        return undefined;
    }

    if (!(result instanceof cls)) {
        return undefined;
    }

    return result as unknown as T;
}

const foos = [new Foo(1), new Bar(2, 'bar'), new Foo(3)];

console.log(get(Foo, foos, 1));
console.log(get(Foo, foos, 2));
console.log(get(Bar, foos, 3));

Playground Link