从父 props 推断类型

2024-03-20

有没有办法让我的子组件了解父组件的 prop 类型?

我不想将它们硬编码到孩子中,因为孩子将被多个具有稍微不同道具的父母使用。

一个简化的例子:

// Parent.tsx

import React, {ReactElement} from "react";

interface Row {
  id: string;
  name: string;
  tags: string[];
}

const Parent = (): ReactElement => {
  const rows: Row[] = [
    {
      id: "1",
      name: "Foo",
      tags: ["new"],
    },
    {
      id: "1",
      name: "Bar",
      tags: ["new", "sale"],
    },
  ];

  const formatRow = (row: Row): ReactElement => (
    <tr key={row.id}>
      <td>{row.id}</td>
      <td>{row.name}</td>
      <td>{row.tags.map(tag => <strong>{tag}</strong>)}</td>
    </tr>
  );

  return <Child formatRow={formatRow} rows={rows} />;
};

export default Parent;
// Child.tsx

import React, {ReactElement} from "react";

const Child = ({formatRow, rows}): ReactElement => {
  const columnCount = Object.keys(rows[0]).length;

  return (
    <table>
      <tbody>
        {rows.map(row => formatRow(row))}
      </tbody>
      <tfoot>
        <tr>
          <td colSpan={columnCount}>Footer</td>
        </tr>
      </tfoot>
    </table>
  );
};

export default Child;

那么也可能有另一个父母,Parent2用这个形状来实现它自己的Row:

// Parent2.tsx

interface Row {
  id: string;
  count: number;
}

const Parent2 = (): ReactElement => {
  // similar code to `Parent` here
};

export default Parent2;

我不知道如何让Child组件知道formatRow期望一个Row并返回一个ReactElement,而 rows 是一个数组Row物体?

我认为泛型可能是答案,但我对此的了解非常有限,因此无论是泛型还是其他任何帮助,我们都会表示赞赏。


通常,如果你想成为argument agnostic你应该使用泛型:


import React, { ReactElement } from "react";

interface Row {
  id: string;
  name: string;
  tags: string[];
}

const Child = <R,>({ formatRow, rows }: { rows: R[], formatRow: (row: R) => ReactElement }): ReactElement => {
  const columnCount = Object.keys(rows[0]).length;

  return (
    <table>
      <tbody>
        {rows.map(row => formatRow(row))}
      </tbody>
      <tfoot>
        <tr>
          <td colSpan={columnCount}>Footer</td>
        </tr>
      </tfoot>
    </table>
  );
};

const Parent = (): ReactElement => {
  const rows: Row[] = [
    {
      id: "1",
      name: "Foo",
      tags: ["new"],
    },
    {
      id: "1",
      name: "Bar",
      tags: ["new", "sale"],
    },
  ];

  const formatRow = (row: Row): ReactElement => (
    <tr key={row.id}>
      <td>{row.id}</td>
      <td>{row.name}</td>
      <td>{row.tags.map(tag => <strong>{tag}</strong>)}</td>
    </tr>
  );

  return <Child formatRow={formatRow} rows={rows} />;
};

操场 https://tsplay.dev/NleJRm

这里有简化版本:

interface ChildProps<R> {
  rows: R[],
  formatRow: (row: R) => ReactElement
}

const Child = <R,>({ formatRow, rows }: ChildProps<R>): ReactElement => {
  const columnCount = Object.keys(rows[0]).length;

  return (
    <table>
      <tbody>
        {rows.map(row => formatRow(row))}
      </tbody>
      <tfoot>
        <tr>
          <td colSpan={columnCount}>Footer</td>
        </tr>
      </tfoot>
    </table>
  );
};

So, R是推断类型rows财产。这就是推理的工作原理。您提供任何价值rows and R将表示值的类型。然后,您可以使用R对于其他属性。

如果您对函数参数的类型推断感兴趣,您可以查看我的article https://catchts.com/infer-arguments

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从父 props 推断类型 的相关文章

随机推荐