繁体   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