reactjstypescript

Problem with extending a generic type for a React component


I have the following generic type argument for a React component, but extended to include two properties - id and label:

const DataTable = <T extends { id: string; label: string }> = () => ...

I'm using the component like this :

<DataTable
  columns={columns}
  orderByDefault={orderByDefault}
  rows={rows}
/>

The type for rows is (string | number)[][].

Getting this type error for rows:

Type '(string | number)[][]' is not assignable to type '{ id: string; label: string; }[]'.
  Type '(string | number)[]' is missing the following properties from type '{ id: string; label: string; }': id, labelts(2322)
types.ts(21, 3): The expected type comes from property 'rows' which is declared here on type 'IntrinsicAttributes & DataTableType<{ id: string; label: string; }>'

How can I get rows to ignore { id: string; label: string } without casting the value as (string | number)[][], which feels like the wrong thing to do here?

Or is there a better way to do this?


Solution

  • You're getting this error because of the generic constraint on your DataTable component:

    const DataTable = <T extends { id: string; label: string }> = () => ...
    

    This means TypeScript expects the rows prop to be of type T[], where each T must have both id and label properties. But you're passing in (string | number)[][], which is an array of arrays — not an array of objects with id and label.

    If DataTable is meant to work with data that has id and label, you should convert your raw rows into an array of objects before passing them:

    const processedRows = rawRows.map(([id, label]) => ({
      id: String(id),
      label: String(label),
    }));
    

    And then pass it as rows property to DataTable component