React Table - types of property 'accessor' are incompatible
Asked Answered
Q

4

7

I am trying out react-table in create-react-app project (version ^7.0.25). I am using the exact example from their quick start documentation. However, I am getting a type error between the accessor and data columns. below is my code,

import * as React from 'react';
import { Solution } from '../../../Models/SolutionModel';
import {useTable} from 'react-table'

interface ICompareTableComponentProps {
  Solutions : Solution[]
}

const CompareTableComponent: React.FunctionComponent<ICompareTableComponentProps> = (props) => {
    
    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',
        },
      ],
      []
    )
  
    const {
      getTableProps,
      getTableBodyProps,
      headerGroups,
      rows,
      prepareRow,
    } = useTable({ columns, data })
  
    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>
    )
          
};
export default CompareTableComponent;

Below is my the full error,

Type '{ Header: string; accessor: string; }[]' is not assignable to type 'Column<{ col1: string; col2: string; }>[]'.
  Type '{ Header: string; accessor: string; }' is not assignable to type 'Column<{ col1: string; col2: string; }>'.
    Type '{ Header: string; accessor: string; }' is not assignable to type 'ColumnInterface<{ col1: string; col2: string; }> & { accessor: "col2"; } & ColumnInterfaceBasedOnValue<{ col1: string; col2: string; }, string>'.
      Type '{ Header: string; accessor: string; }' is not assignable to type '{ accessor: "col2"; }'.
        Types of property 'accessor' are incompatible.
          Type 'string' is not assignable to type '"col2"'.  TS2322

I have tried with converting the columns into objects but no luck.

{
    col1: 'react-table' as any,
    col2: 'rocks' as any,
}

I am sure I am overlooking something very trivial but cannot seem to find the issue. Any help on this will be hugely appreciated.

Quicksilver answered 7/12, 2020 at 13:22 Comment(2)
Did you find a fix for this issue?Checkrein
Not sure if this is the problem here but when using string column accessors you should put as const at the end: accessor: 'col1' -> accessor: 'col1' as constAdulterant
T
8

your useMemo lacks typing

const columns = useMemo<Column<{col1: string}>[]>(() => [
  {
    col1: 'hello world',
  },
], [])
Trombidiasis answered 9/12, 2020 at 11:18 Comment(2)
No, that doesn't fix the issue. Type '{ col1: string; }' is not assignable to type 'Column<{ col1: string; }>'. Object literal may only specify known properties, and 'col1' does not exist in type 'Column<{ col1: string; }>'.Checkrein
@ElioBriceño You would need to type the memo as an array of columns: useMemo<Column<{col1: string}>[ ]>Tolentino
V
2

Check this topic here: https://github.com/ggascoigne/react-table-example/issues/3

Basically you need to define:

const columns: Array<Column<{ col1: string; col2: string }>> = useMemo(

.. or use an interface for the data rows:

const columns: Array<Column<DataInterface>> = ...
Versicular answered 8/7, 2021 at 12:20 Comment(1)
interface Data { name: string } const column: Column<Data> = { accessor: 'name' } Shouldn't that work? TS2322: Type '"name"' is not assignable to type 'Accessor<Data> | (Accessor<Data> & "name") | undefined'.Post
I
1

Things which worked for me:

  • Created an interface

    interface Data {
     id: number;
     first_name: string;
     last_name: string;
     email: string;
     date_of_birth: string;
     age: number;
     country: string;
     phone: string
    }
    
  • Define columns as follows:

    const columns = React.useMemo<Column<Data>[]>(
     () => [
         { Header: "ID", accessor: "id" },
         { Header: "First name", accessor: "first_name" },
         { Header: "Last name", accessor: "last_name" },
         { Header: "Email", accessor: "email" },
         { Header: "Date of Birth", accessor: "date_of_birth" },
         { Header: "Age", accessor: "age" },
         { Header: "Country", accessor: "country" },
         { Header: "Phone", accessor: "phone" },
     ],
     []
    

    );

Infighting answered 13/11, 2022 at 10:56 Comment(0)
H
1

These are the steps I took to solve this:

1. Define table data interface

interface ITableData {
  id: number;
  first_name: string;
  last_name: string;
  email: string;
  date_of_birth: string;
  age: number;
  country: string;
  phone: string;
}

2. Define generic type for useMemo on columns

import { Column } from "react-table";

const columns = useMemo<readonly Column<ITableData>[]>(() => COLUMNS, []);

3. cast accessor as const

const COLUMNS = [
  {
    Header: "ID",
    accessor: "id" as const
  },
  {
    Header: "First Name",
    accessor: "first_name" as const
  },
  {
    Header: "Last Name",
    accessor: "last_name" as const
  },
  {
    Header: "Email",
    accessor: "email" as const
  },
  {
    Header: "Date Of Birth",
    accessor: "date_of_birth" as const
  },
  {
    Header: "Age",
    accessor: "age" as const
  },
  {
    Header: "Country",
    accessor: "country" as const
  },
  {
    Header: "Phone",
    accessor: "phone" as const
  },
]


export default COLUMNS;

My data looks like this:

[
{"id":1,"first_name":"Torie","last_name":"Rustman","email":"[email protected]","date_of_birth":"1979-11-16T23:04:32Z","age":45,"country":"Argentina","phone":"6844103517"},
...
]
Horripilate answered 11/6, 2023 at 3:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.