0

不确定这是否可能,但这与keyof我很难思考的问题有关...

我目前有这个界面:

interface Column<T> {
  header: string;
  field: keyof T;
  format?: (value: any) => string;
}

它的第一个用途是在给定对象和列的列表的情况下创建呈现表格的东西。

const rows = [{name: 'Alice', age: 18}, {name: 'Bob', age: 12}];

type Row = typeof rows[0];

const columns: Column<Row>[] = [
  {
    header: 'Name',
    field: 'name',
    format: value => value.toUpperCase(),
  },
  {
    header: 'Age',
    field: 'age',
    format: value => value.toLocaleString(),
  },
];

const renderTable = <T>(rows: T[], columns: Columns<T>[]) { ... }
renderTable(rows, columns);

有没有办法摆脱函数中的any类型format?以某种方式“链接” keyof Toffieldvalueof format?即第一列value应该是string,第二列应该是number


(我知道手动打印这些会很容易,但也将在此表中添加一些自动魔法的东西,这将利用fieldand format

4

1 回答 1

2

一种方法是依赖 TypeScript 的映射类型

Key in keyof这将通过泛型传递的 ( ) 中的每个键 ( ) “映射” Row

然后,对于每个Row键(例如:nameageadmin),我们将为其分配一个您使用属性 和 勾勒出的形状headerfield对象format

然而,既然我们现在知道我们正在使用一个特定的键(例如:) ,age我们可以使用它Key来引用age这个映射类型并Row[Key]引用age( number) 的类型。

最后,您不想要带有嵌套对象的键,您只想要对象,这样我们就可以有效地“提取”这些值[keyof Row],查找所有值,"age" | "name" | "admin"剩下的是所有可能列的联合类型fieldformat正确输入。

type Columns<Row> = {
  [Key in keyof Row]: {
    header: string;
    field: Key,
    format?: (value: Row[Key]) => string;
  }
}[keyof Row]

const rows = [{name: 'Alice', age: 18, admin: true }, {name: 'Bob', age: 12, admin: false}];

type Row = typeof rows[0];

const columns: Columns<Row>[] = [
  {
    header: 'Name',
    field: 'name',
    format: value => value.toUpperCase(), // value: string
  },
  {
    header: 'Age',
    field: 'age',
    format: value => value.toLocaleString(), // value: number
  },
 {
    header: 'Admin',
    field: 'admin',
    format: value => value.toString(), // value: boolean
  },
];

打字稿游乐场

于 2019-09-19T14:25:52.117 回答