skip to Main Content

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 "@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;

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?

3

Answers


  1. 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 "@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;
    

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

    import { YourType } from 'your-module'
    
    <TableRowsComponent<YourType> rows={yourRows} headings={yourHeadings} />
    
    Login or Signup to reply.
  2. For those cases, you can use generic typing !

    interface Props<T> {
      rows?: T[];
      headings: HeadingsTypes[];
    }
    
    const TableRowsComponent = <T>({ rows, headings }: Props<T>) => {
    

    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<{id: string, name: string}>
    <TableRowsComponent rows={[{id: '1', name: 'Hello'}]} />
    

    See the doc for more information

    Login or Signup to reply.
  3. 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 "@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;
    

    In this example, we’ve added a generic type parameter T to the component definition, which extends Record<string, any>. 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:

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

    Replace MyRowType with the type of your rows.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search