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

p8h8hvxi  于 2023-05-19  发布在  TypeScript
关注(0)|答案(3)|浏览(220)

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

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} />

示例二:

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} />

现在,从类型脚本的Angular 来看,传递DataType是propsTableProps类型的参数时出现了问题
我该怎么办?我可以传递类型Typescript到Props react吗?或者有没有一种方法可以动态地做到这一点?
因此,知道对于这两个示例:

示例1:

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

示例2:

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

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

wbrvyc0a

wbrvyc0a1#

使用泛型从传递的数据推断类型。您需要将组件从箭头函数转换为标准函数,因为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>
  );
}
yxyvkwin

yxyvkwin2#

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

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

92dk7w1h3#

以上两个答案都是正确的。如果有人想知道如何在调用<Table />时传递自定义类型,下面是如何做到这一点-

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

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

相关问题