为农业网格中的行数据创建动态类型
Create a dynamic type for row data in ag grid
我正在尝试使用 ag-grid 开发一个独立的组件。我会将列定义从我的应用程序传递到这个独立组件,因此我将其设置为输入 属性,类型如下:
interface ColumnDef {
field: string;
headerName: string;
}
@Input() colDef: ColumnDef[];
现在如您所见,我可以通过具有不同 ID 的主机(我将在其中使用此通用组件)应用程序传递我想要的任意数量的列,并且工作正常。
现在的要求是我还想在公共组件内动态定义 ag-grid 的行数据类型。
假设我将列定义传递为:
[{field: 'colA', headerName: 'Col A'},
{field: 'colB', headerName: 'Col B'}]
所以当组件接收到这个列定义时,它应该动态创建一个行数据类型为
interface rowData {
colA: string;
colB: string;
}
同样,如果我将列定义传递为
[{field: 'colA', headerName: 'Col A'},
{field: 'colB', headerName: 'Col B'},
{field: 'colC', headerName: 'Col C'}]
行数据类型应创建为
interface rowData {
colA: string;
colB: string;
colC: string;
}
这样我就可以使用这个界面来输入我的行数据。
有什么办法可以实现吗?
提前致谢。
给定一些这样的数组:
const colDef = [{field: 'colA', headerName: 'Col A'},
{field: 'colB', headerName: 'Col B'},
{field: 'colC', headerName: 'Col C'}] as const;
我们可以有这些类型:
type FieldNames<T> = T extends ReadonlyArray<{ field: infer U }> ? U : never;
type Rows<T> = FieldNames<T> extends string ? Record<FieldNames<T>, string> : never;
所以两者
FieldNames<typeof colDef>
是 'colA' | 'colB' | 'colC'
Rows<typeof colDef>
是 { colA: string; colB: string; colC: string }
.
但是,对于您当前的 ColumnDef
类型,typeof colDef
是 ColumnDef
,因此 FieldNames<typeof colDef>
将是 Record<string, string>
,这不是特别有用。要解决此问题,我们需要向组件 class 添加一个类型参数,如下所示:
class CustomGridComponent<T extends ColumnDef> implements OnInit /* or what have you */ {
@Input() colDef: ReadonlyArray<T> = [] as const;
...
}
(顺便说一下,使用 ReadonlyArray
可以让您通过在数组末尾添加 as const
来获取列定义的类型 'for free'。如果您可以手动操作定义一些 interface ABCColDef { field: 'colA' | 'colB' | 'colC'; ... }
然后 ReadonlyArray
是没有必要的。)
我正在尝试使用 ag-grid 开发一个独立的组件。我会将列定义从我的应用程序传递到这个独立组件,因此我将其设置为输入 属性,类型如下:
interface ColumnDef {
field: string;
headerName: string;
}
@Input() colDef: ColumnDef[];
现在如您所见,我可以通过具有不同 ID 的主机(我将在其中使用此通用组件)应用程序传递我想要的任意数量的列,并且工作正常。
现在的要求是我还想在公共组件内动态定义 ag-grid 的行数据类型。
假设我将列定义传递为:
[{field: 'colA', headerName: 'Col A'},
{field: 'colB', headerName: 'Col B'}]
所以当组件接收到这个列定义时,它应该动态创建一个行数据类型为
interface rowData {
colA: string;
colB: string;
}
同样,如果我将列定义传递为
[{field: 'colA', headerName: 'Col A'},
{field: 'colB', headerName: 'Col B'},
{field: 'colC', headerName: 'Col C'}]
行数据类型应创建为
interface rowData {
colA: string;
colB: string;
colC: string;
}
这样我就可以使用这个界面来输入我的行数据。 有什么办法可以实现吗?
提前致谢。
给定一些这样的数组:
const colDef = [{field: 'colA', headerName: 'Col A'},
{field: 'colB', headerName: 'Col B'},
{field: 'colC', headerName: 'Col C'}] as const;
我们可以有这些类型:
type FieldNames<T> = T extends ReadonlyArray<{ field: infer U }> ? U : never;
type Rows<T> = FieldNames<T> extends string ? Record<FieldNames<T>, string> : never;
所以两者
FieldNames<typeof colDef>
是'colA' | 'colB' | 'colC'
Rows<typeof colDef>
是{ colA: string; colB: string; colC: string }
.
但是,对于您当前的 ColumnDef
类型,typeof colDef
是 ColumnDef
,因此 FieldNames<typeof colDef>
将是 Record<string, string>
,这不是特别有用。要解决此问题,我们需要向组件 class 添加一个类型参数,如下所示:
class CustomGridComponent<T extends ColumnDef> implements OnInit /* or what have you */ {
@Input() colDef: ReadonlyArray<T> = [] as const;
...
}
(顺便说一下,使用 ReadonlyArray
可以让您通过在数组末尾添加 as const
来获取列定义的类型 'for free'。如果您可以手动操作定义一些 interface ABCColDef { field: 'colA' | 'colB' | 'colC'; ... }
然后 ReadonlyArray
是没有必要的。)