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

Has*_*tin 6 typescript reactjs typescript-generics react-props react-typescript

我想创建一个通用的 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>
  );
};
Run Code Online (Sandbox Code Playgroud)

这样,我的想法是我可以轻松创建表,如下所示:

示例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} />
Run Code Online (Sandbox Code Playgroud)

示例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} />
Run Code Online (Sandbox Code Playgroud)

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

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

因此,对于这两个例子:

示例1:

type DataType = {
  firstname: string;
  lastname: string;
}
Run Code Online (Sandbox Code Playgroud)

例2:

type DataType = {
  company: string;
  nb_employees: number;
  country: string;
}
Run Code Online (Sandbox Code Playgroud)

如何管理TableProps<DataType>反应组件道具中的类型。知道它将是一个通用的 Table 组件 => 因此 DataType 实际上是动态的。

谢谢

Ori*_*ori 7

使用泛型从您传递的数据推断类型。您需要将组件从箭头函数转换为标准函数,因为 TS 无法在箭头函数中使用 JSX 进行泛型。

示例:()。

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>
  );
}
Run Code Online (Sandbox Code Playgroud)


lib*_*bik 6

这可以根据 typescript 文档使用箭头函数来完成 https://wanago.io/2020/02/17/typescript-generics-discussing-naming-conventions/ 箭头函数部分

 export const Table = <T,>({ heads, rows }: TableProps<T>) => {

    
Run Code Online (Sandbox Code Playgroud)

  • 我的回答是,在这种情况下你仍然可以使用箭头函数组件。编辑以仅包含更改的代码(如果这使它更清晰的话),谢谢 (7认同)