[英]Typescript using mapped types with arrays
我正在嘗試將映射類型與 typescript 一起使用,這應該是可能的,但遇到了一些問題。
假設我有 3 個課程:
class A {
public foo1 = 1;
}
class B {
public foo2 = 1;
}
class C {
public foo3 = 1;
}
const base = [A, B, C] as const;
基本上,我想要的是將base
傳遞給一些 function,並取回一個包含 3 個匹配實例的數組。
type CTOR = new(...args: any[]) => any
function instantiate1<T extends ReadonlyArray<CTOR>>(arr: T): {[K in keyof T]: T[K]} {
const items = arr.map(ctor => new ctor());
return items as any; //Don't mind about breaking type safety inside the function
}
現在返回:
const result1 = instantiate2(base) //type is [typeof A, typeof B, typeof C]
這是有道理的,因為我還沒有真正“映射”類型,只是確保語法有效。
但是,如果我嘗試實際 map 類型:
function instantiate2<T extends ReadonlyArray<CTOR>>(arr: T): {[K in keyof T]: InstanceType<T[K]>} {
const items = arr.map(ctor => new ctor());
return items as any; //Don't mind about breaking type safety inside the function
}
我收到T[K]
不滿足實例類型約束的錯誤。
任何人作為解決方法的想法?
根據microsoft/Typescript#27995 ,這是 TypeScript 中的一個已知錯誤。 這是一個相當老的問題,並且在“積壓”中,所以我不希望它很快得到修復。
解決方法:
將T[K]
顯式約束為所需的構造函數類型。 我通常使用Extract<T, U>
實用程序類型來執行此操作,如下所示:
declare function instantiate<T extends ReadonlyArray<Ctor>>(arr: T): {
[K in keyof T]: InstanceType<Extract<T[K], Ctor>>
};
const result = instantiate(base);
// const result: readonly [A, B, C]
或者,您可以將InstanceType<T>
實用程序類型替換為您自己的版本,該版本不關心T
是否是構造函數。 現有的類型定義是:
type InstanceType<T extends new (...args: any) => any> =
T extends new (...args: any) => infer R ? R : any;
因此,您可以將其放松為:
type MyInstanceType<T> = // no constraint on T
T extends new (...args: any) => infer R ? R : any;
然后您的原始版本按預期工作:
declare function instantiate<T extends ReadonlyArray<Ctor>>(arr: T): {
[K in keyof T]: MyInstanceType<T[K]>
};
const result = instantiate(base);
// const result: readonly [A, B, C]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.