[英]Typescript inline object constructor with generics results in too broad type
[英]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.