簡體   English   中英

如何在此泛型類型內的屬性的泛型接口內定義類型

[英]How to define a type inside a generic interface for a property inside this generic type

例子:

export interface Column<T> {
    field: string;
    columnFormatter?: (props: {
        value: any/** field type inside T**/; data: T; node: any
    }) => void;
}

field 是類型 T 內的屬性的名稱,我怎么能說該值是該類型?

export interface IPurchase {
    id: string;
    name: string;
    purchaseDate: Date;
}

let doSomethingWithMyDate: (myDate: Date) => (true);


const columns: Array<Column<IPurchase>> = [
    {
        field: "purchaseDate", /* "purchaseDate" must be inside IPurchase */
        columnFormatter: ({ value /* must identify that this is a Date */ }) => 
            doSomethingWithMyDate(value)

    }];

為了表示field屬性與columnFormatterprops參數的value屬性類型之間的相關性,您需要Column<T>是一個聯合類型,其中T的每個鍵都有一個成員。 例如,給定您的IPurchase示例,您需要Column<IPurchase>

type ColumnIPurchase = {
    field: "id";
    columnFormatter?: ((props: {
        value: string;
        data: IPurchase;
        node: any;
    }) => void);
} | {
    field: "name";
    columnFormatter?: ((props: {
        value: string;
        data: IPurchase;
        node: any;
    }) => void) 
} | {
    field: "purchaseDate";
    columnFormatter?: ((props: {
        value: Date;
        data: IPurchase;
        node: any;
    }) => void);
}

這將按需要運行:

const columns: Array<Column<IPurchase>> = [
    {
        field: "purchaseDate",
        columnFormatter: ({ value }) => doSomethingWithMyDate(value)
    },
    {
        field: "name",
        columnFormatter: ({ value }) => doSomethingWithMyDate(value) // error!
        //  string isn't a Date ----------------------------> ~~~~~ 
    }
];

所以這就是我們想要的......我們如何編寫Column<T>來做到這一點?


這是一種方法:

type Column<T> = { [K in keyof T]-?: {
    field: K;
    columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void;
} }[keyof T]

這種類型的一般形式{[K in keyof T]-?: F<K>}[keyof T]被稱為分布式對象類型,如microsoft/TypeScript#47109中所創造的; 我們在keyof T中的鍵上創建一個映射類型,然后立即使用keyof T對其進行索引,以便為 keyof T 中的每個鍵K獲得F<K>的並keyof T

特別是在這里我們正在計算{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; } { field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; } 其中{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }是鍵的類型, T[K] K該鍵對應的屬性值的類型。

您可以驗證Column<IPurchase>的計算結果完全符合所需的類型。

Playground 代碼鏈接

暫無
暫無

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

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