gpt4 book ai didi

typescript : Filter on keyof type parameter

转载 作者:行者123 更新时间:2023-12-04 15:29:32 27 4
gpt4 key购买 nike

我正在使用 typescript 3.8.3 并尝试动态查找某种类型的键并使用它们来生成其他对象。

我有一个 Detail对象并想用它动态生成一个 Column对象仅基于 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 能够检测到任何错误对象变化 ?

谢谢 !

最佳答案

为了排除映射类型的某些列,我们需要使用中间辅助类型,允许我们仅选择 key 尊重我们的条件,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

关于 typescript : Filter on keyof type parameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61506794/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com