7

I've set up my React project with Typescript and React-Table. I was following the Quick Start Guide from the React-Table website and got an error.

 const data = React.useMemo(
   () => [
     {
       col1: 'Hello',
       col2: 'World',
     },
     {
       col1: 'react-table',
       col2: 'rocks',
     },
     {
       col1: 'whatever',
       col2: 'you want',
     },
   ],
   []
 )

const columns = React.useMemo(
    () => [
      {
        Header: 'Column 1',
        accessor: 'col1', // accessor is the "key" in the data
      },
      {
        Header: 'Column 2',
        accessor: 'col2',
      },
    ],
    []
  )



I get an error when doing const tableInstance = useTable({ columns, data }).

Type '{ Header: string; accessor: string; }[]' is not assignable to type 'readonly Column<{ col1: string; col2: string; }>[]'. Type '{ Header: string; accessor: string; }' is not assignable to type 'Column<{ col1: string; col2: string; }>'.

I barely just started getting into this so I don't really know what's going on. Here is a code sandbox with a recreation of the problem: Sandbox

2
  • Sandbox is empty. Please update Commented Dec 19, 2021 at 16:22
  • @TusharShahi Sandbox has been updated. Commented Dec 21, 2021 at 8:12

3 Answers 3

11

Seems that TypeScript fails with type inference, so I gave him the hint by

  • Introducing new type type Cols = { col1: string; col2: string };
  • Explicitly stating type for const columns: Column<Cols>[] = ...

Full working example is here:

import { useTable, TableOptions, Column } from "react-table";
import React from "react";

type Cols = { col1: string; col2: string };

export default function App() {
  const data = React.useMemo(
    (): Cols[] => [
      {
        col1: "Hello",
        col2: "World"
      },
      {
        col1: "react-table",
        col2: "rocks"
      },
      {
        col1: "whatever",
        col2: "you want"
      }
    ],
    []
  );

  const columns: Column<{ col1: string; col2: string }>[] = React.useMemo(
    () => [
      {
        Header: "Column 1",
        accessor: "col1" // accessor is the "key" in the data
      },
      {
        Header: "Column 2",
        accessor: "col2"
      }
    ],
    []
  );

  const options: TableOptions<{ col1: string; col2: string }> = {
    data,
    columns
  };

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable(options);

  return (
    <table {...getTableProps()} style={{ border: "solid 1px blue" }}>
      <thead>
        {headerGroups.map((headerGroup) => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map((column) => (
              <th
                {...column.getHeaderProps()}
                style={{
                  borderBottom: "solid 3px red",
                  background: "aliceblue",
                  color: "black",
                  fontWeight: "bold"
                }}
              >
                {column.render("Header")}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map((row) => {
          prepareRow(row);
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map((cell) => {
                return (
                  <td
                    {...cell.getCellProps()}
                    style={{
                      padding: "10px",
                      border: "solid 1px gray",
                      background: "papayawhip"
                    }}
                  >
                    {cell.render("Cell")}
                  </td>
                );
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

Sign up to request clarification or add additional context in comments.

1 Comment

so nice! I was struggling for hours in a more complex scenario where I want to implement some filters connected to the table, but displayed outside it. This was of big help, thanks!
6

I was facing the same problem then found this solution, add as 'const' to your columns object like this:

[
  {
    Header: 'Id',
    accessor: 'id' as const,
  },
  {
    Header: 'Column 1',
    accessor: 'column_1' as const,
  },
  {
    Header: 'Column 2',
    accessor: 'column_2' as const,
  },
  {
    Header: 'Column 3',
    accessor: 'column_3' as const,
  },
]

1 Comment

You can also simply add as const once to the end of the statement, after the last square bracket.
1

It'll work this out for you if you do the following:

https://github.com/tannerlinsley/react-table/issues/2970#issuecomment-756364081

Then you just need to set your columns type to columns[] in your config file

export const headers: Column[] = [
  {
    Header: "ID",
    accessor: "id", // accessor is the "key" in the data
  },
.....

Then in you table consuming component you do

  const columns = useMemo(() => headers, []);
  const data = useMemo(() => people, []);

  const tableInstance = useTable({ columns, data });

Or you can do it all in the one file of course

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.