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