簡體   English   中英

Typescript: 過濾 keyof 類型參數

[英]Typescript : Filter on keyof type parameter

我正在使用 typescript 3.8.3 並嘗試動態查找某種類型的密鑰並使用它們來生成另一個 object。

我有一個Detail object 並希望使用它僅基於Desc類型的屬性動態生成一個Column object 。 這是我想要做的簡化代碼:

// Model
interface Desc {
    creationDate: Date;
}

interface Address extends Desc {
    zipCode: number;
    adressName: string;
}

interface Order extends Desc {
    id: number;
    orderName: string;
}

interface Detail {
    name: string;
    address: Address[];
    orders: Order[];
}
// Table column configuration
interface Column<T> {
    field: keyof T;
    active: boolean;
}

type ColumnConfig<T> = { [P in keyof T]: Column<T[P] extends Desc ? P : never>[] };

const config: ColumnConfig<Detail> = {
    address: [
        {
            field: "zipCode",
            active: true 
        }, 
        {
            field: "addressName",
            active: true
        }
    ],
    order: [
        {
            field: "id",
            active:false
        },
        {
            field: "orderName",
            active: false
        }
    ],
    // Detail.name should not be available but it is

}

我如何從編譯器的幫助中受益來構建我的config object 並因此能夠在我的Detail object 更改時檢測到任何錯誤?

謝謝 !

為了排除映射類型的某些列,我們需要使用中間輔助類型,允許我們 select 僅符合我們條件的T[K] extends Desc

type ConfigurableColumnsKeys<T extends object> = {
  [K in keyof T]: T[K] extends Desc ? K : never
}[keyof T];

鑒於此, ColumnConfig只需要 map 超過此泛型類型,而不是原始keyof T

type ColumnConfig<T extends object> = {
  [P in ConfigurableColumnsKeys<T>]: Column<P>[] 
};

然后您的配置 object 將被正確驗證:

  // Error
  name: [
    { field: 'abc', active: true }
  ]

如果您也需要允許arrays (即Address[]而不是Address ),您可以更改幫助器類型,檢查T extends Desc[] 此外,您還需要一個UnboxArray助手,為您的列配置提取項目值Order[] -> Order

type ConfigurableColumnsKeys<T extends object> = {
  [K in keyof T]: T[K] extends Desc ? K : T[K] extends Desc[] ? K : never
}[keyof T];

type UnboxArray<T> = T extends Array<infer V> ? V : T;

type ColumnConfig<T extends object> = {
  [P in ConfigurableColumnsKeys<T>]: Column<UnboxArray<T[P]>>[]
};

您可以在以下操場上看到它: Playground Link

暫無
暫無

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

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