簡體   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