繁体   English   中英

使用泛型和构造函数的TypeScript强制转换类型?

[英]TypeScript cast type using generics and constructor?

我有一个基类,以及那里的子类。

这些类的实例将以基类的类型放入集合中。

class Type extends Object {
    public static ID = 'type';
    public id = 'type';
    constructor() { super(); }
}

class TypeA extends Type {
    public static ID = 'type-a';
    public id = 'type-a';
    constructor() { super(); }
    public onlyA() { return 'only A has this method'; }
}

class TypeB extends Type {
    public static ID = 'type-b';
    public id = 'type-b';
    constructor() { super(); }
    public onlyB() { return 'only B has this method'; }
}

// Discards subclass type information:
const list: Type[] = [
    new TypeA(),
    new TypeB()
];

// Has inferred type: Type
const list0 = list[0];

现在,如果我知道正确的类型,则可以使用as来提升类型:

const list0asA = list0 as TypeA;
list0asA.onlyA();

但是,我想做的是创建一个将动态检查实例的泛型函数,并返回提升的类型,如果不匹配则返回null

我提出了以下建议,但这并不完全正确:

function castOrNull<
    C extends typeof Type
>(value: Type, Constructor: C): C | null {
    if (value.id !== Constructor.ID) {
        return null;
    }
    return value as C;
}

const list0castA = castOrNull(list0, TypeA);
if (list0castA) {
    list0asA.onlyA();
}

问题是我不是试图将变量强制转换为构造函数类型,而是该构造函数实例的类型,因此as和return类型不正确。

或者,这确实可行,但是需要显式设置泛型类型,这意味着在使用时两次指定类型,这比理想情况要差。

function castOrNull<
    T extends Type
>(value: Type, Constructor: typeof Type): T | null {
    if (value.id !== Constructor.ID) {
        return null;
    }
    return value as T;
}

const list0upA = castOrNull<TypeA>(list0, TypeA);
if (list0castA) {
    list0asA.onlyA();
}

是否可以创建该通用函数而无需两次指定类型?

从Typescript 2.8开始,将InstanceType<T>类型添加到标准库中,该库从构造函数T提取其实例的类型。 因此,对于您的摘要,您可以将其用于返回类型并进行强制转换:

function castOrNull<
    C extends typeof Type
>(value: Type, Constructor: C): InstanceType<C> | null {
    if (value.id !== Constructor.ID) {
        return null;
    }
    return value as InstanceType<C>;
}

// All good now
const list0castA = castOrNull(list0, TypeA);
if (list0castA) {
    list0asA.onlyA();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM