Typescript 泛型的自动类型解析

Typescript 泛型的自动类型解析,typescript,Typescript,我想为具有以下属性的表列定义一个接口: 标题:列的标题 键:特定模型中属性的键(因此我可以获取值) valueFormatter:用于格式化返回字符串的值的任何函数 valueFormatter函数应获取一个参数,该参数的类型与属性(键)相同。像这样 export interface Column<T, P extends keyof T> { label: string; key: P; valueFormatter?: (value: T[P]) => st

我想为具有以下属性的表列定义一个接口:

  • 标题:列的标题
  • 键:特定模型中属性的键(因此我可以获取值)
  • valueFormatter:用于格式化返回字符串的值的任何函数
valueFormatter函数应获取一个参数,该参数的类型与属性(键)相同。像这样

export interface Column<T, P extends keyof T> {
  label: string;
  key: P;
  valueFormatter?: (value: T[P]) => string
};
导出接口列{
标签:字符串;
关键词:P;
valueFormatter?:(值:T[P])=>字符串
};
有没有办法在没有明确定义“p”类型的情况下在另一个接口中使用此选项

export interface Table<T> {
  data: T[];
  columns: Column<T>[];
}
interface Person {
  name: string;
  age: number;
}

const table1: TableWithColumnObject<Person> = {
  data: [{ name: "Alice", age: 35 }, { name: "Bob", age: 38 }],
  columnObject: {
    name: {
      label: "Name",
      key: "name",
      valueFormatter: name => name
    },
    age: {
      label: "Age",
      key: "age",
      valueFormatter: age => "" + age
    }
  }
};
const table2: TableWithColumnArray<Person> = {
  data: [{ name: "Alice", age: 35 }, { name: "Bob", age: 38 }],
  columnArray: [
    {
      label: "Name",
      key: "name",
      valueFormatter: name => name
    },
    {
      label: "Age",
      key: "age",
      valueFormatter: age => "" + age
    }
  ]
};
导出接口表{
数据:T[];
列:第[]列;
}

或者:如果没有p-Generic,我如何定义列接口,并使用“key”和“valueFormatter”确保安全?

就个人而言,我倾向于将
columns
作为一个对象,每个
T
的键都有一个属性,因为您可能不想冒丢失其中一个列的风险:

interface Column<T, P extends keyof T> {
  label: string;
  key: P;
  valueFormatter?: (value: T[P]) => string;
}

interface TableWithColumnObject<T> {
  data: T[];
  columnObject: { [K in keyof T]: Column<T, K> };
}
如果您不关心缺少其中一列(或者您可能希望能够缺少某些列或包含重复的列),那么您可以通过稍微复杂一点的方式使用
columnObject
映射类型来获得所需的类型:

interface TableWithColumnArray<T> {
  data: T[];
  columnArray: { [K in keyof T]: Column<T, K> }[keyof T][];
}
希望有帮助。祝你好运


感谢您提供了非常好且详细的答案。如果我不想总是被迫为给定的数据数组定义每一列,我将使用第二种方法。你有关于语法的更多信息吗?特别是为什么我必须定义columnObject上的所有属性,如果我省略“[keyof T][]”?类型
{[K in keyof T]:Column}
是一个与
T
具有相同键的属性,但属性类型是映射的。如果我们在
keyof T
属性上使用a(因此
{…}[keyof T]
),那就是所有这些属性的并集。然后,如果我们用
[]
覆盖该类型,我们说我们需要一个数组。假设
T
Person
{[K in keyof T]:Column}
变成
{name:Column;age:Column