Reactjs 中的 Typescript 如何制作动态 Props 类型?

Typescript in Reactjs How to make dynamic Props type?

我想创建一个通用 Table 组件。


type HeadCell<DataType> = {
  id: keyof DataType;
  label: string;
};

type TableProps<DataType> = {
  heads: HeadCell<DataType>[];
  rows: Array<DataType>;
};

const Table = ({ heads, rows }: TableProps) => {
  const ColumnsKeys = heads.map(
    (item: { [key: string]: any }) => item.id
  );

  return (
    <table>
      <tr>
        {heads.map((head: string, headKey: number) => {
          return (
            <th key={headKey}>{head.label}</th>
          );
        })}
      </tr>

      {rows.map((row, rowKey) => {
        return (
          <tr key={rowKey}>
            {ColumnsKeys.map((column: string, columnKey: number) => {
              return (
                <td key={columnKey}>{row[column]}</td>
              );
            })}
          </tr>
        );
      })};  

    </table>
  );
};

这样,我的想法是我可以轻松地创建 Table,例如:

示例 1:

const heads = [
  {
    id: 'firstname',
    label: 'Firstname'
  },
  {
    id: 'lastname',
    label: 'Lastname'
  }
];

const rows = [
  {
    firstname: 'John',
    lastname: 'Adams'
  },
  {
    firstname: 'Paul',
    lastname: 'Walker'
  },
];

<Table heads={heads} rows={rows} />

示例 2:

const heads = [
  {
    id: 'company',
    label: 'Company'
  },
  {
    id: 'nb_employees',
    label: 'Number of employees'
  },
  {
    id: 'country',
    label: 'Country'
  }
];

const rows = [
  {
    company: 'Vody aho',
    nb_employees: 1590,
    country: 'Hong Kong'
  },
  {
    company: 'Royal spirit',
    nb_employees: 15,
    country: 'USA'
  },
];

<Table heads={heads} rows={rows} />

现在从打字稿的角度来看,我在传递 DataType 时遇到问题,它是道具类型的参数 Table道具

我该如何处理?我可以将类型 Typescript 传递给 Props 反应吗?或者有没有办法动态地做到这一点?

因此知道对于这两个示例:

例1:

type DataType = {
  firstname: string;
  lastname: string;
}

例2:

type DataType = {
  company: string;
  nb_employees: number;
  country: string;
}

如何管理 TableProps<DataType> 类型的 React 组件道具。知道它将是一个通用的 Table 组件 => 所以 DataType 实际上是动态的。

谢谢

使用泛型从您传递的数据中推断出类型。您需要将组件从箭头函数转换为标准函数,因为 TS 可以使用 JSX (sandbox).

type HeadCell<DataType> = {
  id: Extract<keyof DataType, string>;
  label: string;
};

type TableProps<DataType> = {
  heads: HeadCell<DataType>[];
  rows: Array<DataType>;
};

export function Table<T>({ heads, rows }: TableProps<T>) {
  const ColumnsKeys = heads.map((item: HeadCell<T>) => item.id);

  return (
    <table>
      <tr>
        {heads.map((head, headKey) => {
          return <th key={headKey}>{head.label}</th>;
        })}
      </tr>
      {rows.map((row, rowKey) => {
        return (
          <tr key={rowKey}>
            {ColumnsKeys.map((column: keyof T, columnKey) => {
              return <td key={columnKey}>{row[column]}</td>;
            })}
          </tr>
        );
      })}
    </table>
  );
}