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