为农业网格中的行数据创建动态类型

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 colDefColumnDef,因此 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 是没有必要的。)