typescript - 打字稿:过滤keyof类型参数
问题描述
我正在使用 typescript 3.8.3 并尝试动态查找某种类型的键并使用它们来生成另一个对象。
我有一个Detail
对象,想用它来动态生成一个Column
仅基于 type 属性的对象Desc
。这是我想做的简化代码:
// 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
对象,从而能够在我的Detail
对象发生变化时检测到任何错误?
谢谢 !
解决方案
为了排除映射类型的某些列,我们需要使用中间辅助类型,允许我们仅选择符合我们条件的键T[K] extends Desc
:
type ConfigurableColumnsKeys<T extends object> = {
[K in keyof T]: T[K] extends Desc ? K : never
}[keyof T];
鉴于此,ColumnConfig
只需要映射此泛型类型而不是原始类型keyof T
:
type ColumnConfig<T extends object> = {
[P in ConfigurableColumnsKeys<T>]: Column<P>[]
};
然后您的配置对象将被正确验证:
// Error
name: [
{ field: 'abc', active: true }
]
如果您也需要允许数组(即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
推荐阅读
- angular2-services - Angular 2 应用程序中的 HTTP 响应处理
- python - 如何缓存为 Alpine Linux 构建的 python 包 Docker?
- html - z-index 在材质侧导航上无法正常工作
- mysql - SQLite - 对来自三个不同表的列进行算术运算(求和、乘、减等)
- javascript - 单击弹出窗口中的链接
- php - PHP - 动态链接重写 .HTACCESS
- node.js - 禁止访问 Heroku 中的配置变量
- swift - 从 tableviewcell 中的字符串创建图像时崩溃
- c++ - AMQP-CPP - RabbitMQ 事件循环不工作
- openlayers - 如何从 Openlayers 3 中的矢量图层获取特征信息