Why is Tanstack Table giving me a type mismatch in my cell definition

176 Views Asked by At

I've been learning how to use react and typescript recently and am currently trying to use Tanstack Table to define a complicated table using generic types for reusability. I'm running into type errors with how I am trying to spread my custom function for cell definition.

The error:

Argument of type '{ getUniqueValues?: AccessorFn<BulkEditRow, unknown[]> | undefined; footer?: ColumnDefTemplate<HeaderContext<BulkEditRow, unknown>> | undefined; ... 22 more ...; id: string; } | ... 6 more ... | { ...; }' is not assignable to parameter of type 'IdentifiedColumnDef<BulkEditRow, number | null>'. Type '{ getUniqueValues?: AccessorFn<BulkEditRow, unknown[]> | undefined; footer?: ColumnDefTemplate<HeaderContext<BulkEditRow, unknown>> | undefined; ... 22 more ...; id: string; }' is not assignable to type 'IdentifiedColumnDef<BulkEditRow, number | null>'. Types of property 'cell' are incompatible. Type 'ColumnDefTemplate<CellContext<BulkEditRow, unknown>> | undefined' is not assignable to type 'ColumnDefTemplate<CellContext<BulkEditRow, number | null>> | undefined'. Type '(props: CellContext<BulkEditRow, unknown>) => any' is not assignable to type 'ColumnDefTemplate<CellContext<BulkEditRow, number | null>> | undefined'. Type '(props: CellContext<BulkEditRow, unknown>) => any' is not assignable to type '(props: CellContext<BulkEditRow, number | null>) => any'. Types of parameters 'props' and 'props' are incompatible. Type 'CellContext<BulkEditRow, number | null>' is not assignable to type 'CellContext<BulkEditRow, unknown>'. The types of 'cell.column.columnDef' are incompatible between these types. Type 'ColumnDef<BulkEditRow, number | null>' is not assignable to type 'ColumnDef<BulkEditRow, unknown>'. Type 'ColumnDefBase<BulkEditRow, number | null> & StringHeaderIdentifier' is not assignable to type 'ColumnDef<BulkEditRow, unknown>'. Type 'ColumnDefBase<BulkEditRow, number | null> & StringHeaderIdentifier' is not assignable to type 'AccessorFnColumnDefBase<BulkEditRow, unknown> & IdIdentifier<BulkEditRow, unknown>'. Property 'accessorFn' is missing in type 'ColumnDefBase<BulkEditRow, number | null> & StringHeaderIdentifier' but required in type 'AccessorFnColumnDefBase<BulkEditRow, unknown>'.ts(2345) types.d.ts(83, 5): 'accessorFn' is declared here. (property) IdentifiedColumnDef<BulkEditRow, number | null>.header?: ColumnDefTemplate<HeaderContext<BulkEditRow, number | null>> | undefined

I pass to a function that determines what should be returned

export const useEditableCell = <TData extends object>(
  setTableState: React.Dispatch<React.SetStateAction<TableState>>,
  getTableState: TableState,
  customUpdateFunction?: CustomUpdateFunction,
  mode: 'View' | 'Edit' = 'Edit'
) => {
  const editableColumn = useMemo<Partial<ColumnDef<TData>>>(() => {
    return {
      cell: (cellProps) => {
        const isCurrentErrorCell =
          getTableState.errorLocation &&
          cellProps.row.index === getTableState.errorLocation.rowIndex &&
          cellProps.column.id === getTableState.errorLocation.columnId

        const cellValue = cellProps.getValue()
        const displayValue = cellValue === null ? '' : String(cellValue)

        if (
          (getTableState.message != null && !isCurrentErrorCell) ||
          mode === 'View'
        ) {
          return <TableDisplayCell value={displayValue} />
        }

        return (
          <EditableCell
            {...(cellProps as unknown as Cell<TData, unknown>)}
            updateData={
              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
              customUpdateFunction ?? cellProps.table.options.meta!.updateData
            }
            setTableState={setTableState}
          />
        )
      },
    }
  }, [
    getTableState.errorLocation,
    getTableState.message,
    mode,
    customUpdateFunction,
    setTableState,
  ])

  return editableColumn
}

This then returns either a cell that is editable using mui textfield or div with a display value inside.

Here is how the useEditableCell is used:

const editableCell = useEditableCell<BulkEditRow>(
    setTableState,
    getTableState
  )

And then used inside the column definitions here:

 columnHelper.accessor('percentAustralia', {
        id: 'percentAustralia',
        header: () => RenderDefaultHeaderCell('% Australia'),
        size: 12,
        meta: {
          validate: validatePercentageValueInTable,
        },
        ...editableCell,
      }),

I'm just very confused on why this doesn't work when if I were to simply define the column like so:

 cell: (cellProps) => {
    <EditableCell
            {...(cellProps as unknown as Cell<TData, unknown>)}
            updateData={
              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
              cellProps.table.options.meta!.updateData
            }
            setTableState={setTableState}
     />
  }

It works fine. Any help would be appreciated, though everything I am doing is done with a purpose and a specific use case in mind, so I cannot change anything that I am doing.

0

There are 0 best solutions below