如何将类型作为属性传递给可重用组件

huangapple go评论75阅读模式
英文:

how to pass types as props in a reuseable component

问题

我有一个可重用的组件,我将行和标题作为props传递给它,无论我在哪里使用这个组件。我唯一的问题是如何将类型作为props传递给这个组件?

以下是我的可重用组件

import { TableCell, TableRow } from "@mui/material";
import TableCellOperations from "./table-cell-operations.componenet";
import { PropertyListItem } from "@slice/properties.slice";

interface Props {
  rows?: PropertyListItem[];
  headings: HeadingsTypes[];
}

export interface HeadingsTypes {
  id: string;
  title: string;
  label: string;
}

const TableRowsComponent: React.FC<Props> = ({ rows, headings }) => {
  return (
    <>
      {rows?.map((row) => (
        <TableRow key={row.id}>
          {headings.map((heading) => (
            <TableCell key={heading.id} align="center">
              {typeof row[heading.id] === "object" &&
                row[heading.id] !== null
                ? row[heading.id]?.title
                : heading.id === "status"
                ? row.status == 0
                  ? "منقضی"
                  : "فعال"
                : row[heading.id]}
            </TableCell>
          ))}
          <TableCellOperations />
        </TableRow>
      ))}
    </>
  );
};

export default TableRowsComponent;

我的行类型可能因情况而异。在这里,我将PropertyListItem作为行类型,但可能会更改行的类型。因此,我想将行的类型作为props传递给这个可重用组件。我应该怎么做?

英文:

I have a reusable component that i pass rows and headings to it as props where ever i use the component. the only problem i have is how to pass types as props to this component?

here is my reusable component

import { TableCell, TableRow } from &quot;@mui/material&quot;;
import TableCellOperations from &quot;./table-cell-operations.componenet&quot;;
import { PropertyListItem } from &quot;@slice/properties.slice&quot;;

interface Props {
  rows?: PropertyListItem[];
  headings: HeadingsTypes[];
}

export interface HeadingsTypes {
  id: string;
  title: string;
  label: string;
}

const TableRowsComponent: React.FC&lt;Props&gt; = ({ rows, headings }) =&gt; {
  return (
    &lt;&gt;
      {rows?.map((row) =&gt; (
        &lt;TableRow key={row.id}&gt;
          {headings.map((heading) =&gt; (
            &lt;TableCell key={heading.id} align=&quot;center&quot;&gt;
              {typeof row[heading.id] === &quot;object&quot; &amp;&amp; row[heading.id] !== null
                ? row[heading.id]?.title
                : heading.id === &quot;status&quot;
                ? row.status == 0
                  ? &quot;منقضی&quot;
                  : &quot;فعال&quot;
                : row[heading.id]}
            &lt;/TableCell&gt;
          ))}
          &lt;TableCellOperations /&gt;
        &lt;/TableRow&gt;
      ))}
    &lt;/&gt;
  );
};

export default TableRowsComponent;

my rows type could be diffrent by situation. in here i put PropertyListItem as rows types but maybe types of rows change. so i want to pass type of rows as a props to this reuseable component. what should i do?

答案1

得分: 1

我建议将 TableRowsComponent 使用 TypeScript (TS) 使其成为一个泛型组件。这将允许您为 rows 属性使用任何类型。

示例

import { TableCell, TableRow } from "@mui/material";
import TableCellOperations from "./table-cell-operations.component";

interface Props<T> {
  rows?: T[];
  headings: HeadingsTypes[];
}

export interface HeadingsTypes {
  id: string;
  title: string;
  label: string;
}

const TableRowsComponent = <T>({ rows, headings }: Props<T>): React.ReactElement => {
  return (
    <>
      {rows?.map((row, index) => (
        <TableRow key={index}>
          {headings.map((heading) => (
            <TableCell key={heading.id} align="center">
              {typeof (row as any)[heading.id] === "object" &&
                (row as any)[heading.id] !== null
                ? (row as any)[heading.id]?.title
                : heading.id === "status"
                ? (row as any).status == 0
                  ? "منقضی"
                  : "فعال"
                : (row as any)[heading.id]}
            </TableCell>
          ))}
          <TableCellOperations />
        </TableRow>
      ))}
    </>
  );
};

export default TableRowsComponent;

当您使用 TableRowsComponent 时,您可以像这样指定 rows 的类型:

import { YourType } from 'your-module'

<TableRowsComponent<YourType> rows={yourRows} headings={yourHeadings} />
英文:

I would suggest making TableRowsComponent a generic using TS. This will allow you to use any type for the rows prop.

Example:

import { TableCell, TableRow } from &quot;@mui/material&quot;;
import TableCellOperations from &quot;./table-cell-operations.component&quot;;

interface Props&lt;T&gt; {
  rows?: T[];
  headings: HeadingsTypes[];
}

export interface HeadingsTypes {
  id: string;
  title: string;
  label: string;
}

const TableRowsComponent = &lt;T, &gt;({ rows, headings }: Props&lt;T&gt;): React.ReactElement =&gt; {
  return (
    &lt;&gt;
      {rows?.map((row, index) =&gt; (
        &lt;TableRow key={index}&gt;
          {headings.map((heading) =&gt; (
            &lt;TableCell key={heading.id} align=&quot;center&quot;&gt;
              {typeof (row as any)[heading.id] === &quot;object&quot; &amp;&amp; (row as any)[heading.id] !== null
                ? (row as any)[heading.id]?.title
                : heading.id === &quot;status&quot;
                ? (row as any).status == 0
                  ? &quot;منقضی&quot;
                  : &quot;فعال&quot;
                : (row as any)[heading.id]}
            &lt;/TableCell&gt;
          ))}
          &lt;TableCellOperations /&gt;
        &lt;/TableRow&gt;
      ))}
    &lt;/&gt;
  );
};

export default TableRowsComponent;

When you use TableRowsComponent, you will specify the type for rows like this:

import { YourType } from &#39;your-module&#39;

&lt;TableRowsComponent&lt;YourType&gt; rows={yourRows} headings={yourHeadings} /&gt;

答案2

得分: 1

对于这些情况,您可以使用通用类型!

interface Props<T> {
rows?: T[];
headings: HeadingsTypes[];
}

const TableRowsComponent = <T>({ rows, headings }: Props<T>) => {


然后,在将有类型的数组传递到`rows`属性时,类型将自动推断为

// 在这里,TableRowsComponent的props将具有类型
// Props<{id: string, name: string}>
<TableRowsComponent rows={[{id: '1', name: 'Hello'}]} />


[查看更多信息][1]

[1]: https://www.typescriptlang.org/docs/handbook/2/generics.html
英文:

For those cases, you can use generic typing !

interface Props&lt;T&gt; {
  rows?: T[];
  headings: HeadingsTypes[];
}

const TableRowsComponent = &lt;T&gt;({ rows, headings }: Props&lt;T&gt;) =&gt; {

The type will then automatically be infer while passing a typed array into the prop rows

// Here the props of TableRowsComponent will be of type 
// Props&lt;{id: string, name: string}&gt;
&lt;TableRowsComponent rows={[{id: &#39;1&#39;, name: &#39;Hello&#39;}]} /&gt;

See the doc for more information

答案3

得分: 1

将行的类型作为可重用组件的prop之一传递的一种方法是在组件定义中使用泛型类型参数。以下是一个示例:

import { TableCell, TableRow } from "@mui/material";
import TableCellOperations from "./table-cell-operations.componenet";

interface Props<T> {
  rows?: T[];
  headings: HeadingsTypes[];
}

export interface HeadingsTypes {
  id: string;
  title: string;
  label: string;
}

const TableRowsComponent = <T extends Record<string, any>>({ rows, headings }: Props<T>) => {
  return (
    <>
      {rows?.map((row: T) => (
        <TableRow key={row.id}>
          {headings.map((heading) => (
            <TableCell key={heading.id} align="center">
              {typeof row[heading.id] === "object" && row[heading.id] !== null
                ? row[heading.id]?.title
                : heading.id === "status"
                ? row.status == 0
                  ? "منقضی"
                  : "فعال"
                : row[heading.id]}
            </TableCell>
          ))}
          <TableCellOperations />
        </TableRow>
      ))}
    </>
  );
};

export default TableRowsComponent;

在这个示例中,我们在组件定义中添加了一个泛型类型参数T,它扩展了Record<string, any>。这意味着T可以是任何对象类型。然后,我们将T用作Props接口中rows prop的类型,以及map函数中row参数的类型。

当您在代码中使用TableRowsComponent时,可以通过将其作为泛型类型参数传递来指定行的类型,例如:

<TableRowsComponent<MyRowType> rows={myRows} headings={myHeadings} />

MyRowType替换为您的行的类型。

英文:

One way to pass the type of rows as a prop to your reusable component is to use a generic type parameter in the component definition. Here's an example:

import { TableCell, TableRow } from &quot;@mui/material&quot;;
import TableCellOperations from &quot;./table-cell-operations.componenet&quot;;

interface Props&lt;T&gt; {
  rows?: T[];
  headings: HeadingsTypes[];
}

export interface HeadingsTypes {
  id: string;
  title: string;
  label: string;
}

const TableRowsComponent = &lt;T extends Record&lt;string, any&gt;&gt;({ rows, headings }: Props&lt;T&gt;) =&gt; {
  return (
    &lt;&gt;
      {rows?.map((row: T) =&gt; (
        &lt;TableRow key={row.id}&gt;
          {headings.map((heading) =&gt; (
            &lt;TableCell key={heading.id} align=&quot;center&quot;&gt;
              {typeof row[heading.id] === &quot;object&quot; &amp;&amp; row[heading.id] !== null
                ? row[heading.id]?.title
                : heading.id === &quot;status&quot;
                ? row.status == 0
                  ? &quot;منقضی&quot;
                  : &quot;فعال&quot;
                : row[heading.id]}
            &lt;/TableCell&gt;
          ))}
          &lt;TableCellOperations /&gt;
        &lt;/TableRow&gt;
      ))}
    &lt;/&gt;
  );
};

export default TableRowsComponent;

In this example, we've added a generic type parameter T to the component definition, which extends Record&lt;string, any&gt;. This means that T can be any object type. We've then used T as the type of the rows prop in the Props interface, and as the type of the row parameter in the map function.

When you use the TableRowsComponent in your code, you can specify the type of rows by passing it as the generic type argument, like this:

&lt;TableRowsComponent&lt;MyRowType&gt; rows={myRows} headings={myHeadings} /&gt;

Replace MyRowType with the type of your rows.

huangapple
  • 本文由 发表于 2023年7月17日 16:38:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76702745.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定