簡體   English   中英

Typescript 使用映射類型與 arrays

[英]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]

Playground 代碼鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM