reactjs - Waarom geeft Tanstack Table mij een type-mismatch in mijn celdefinitie
Ik ben de laatste tijd bezig met het leren hoe ik React en TypeScript kan gebruiken en probeer momenteel Tanstack Table te gebruiken om een gecompliceerde tabel te definiëren met generieke types voor herbruikbaarheid. Ik loop tegen typefouten aan met hoe ik probeer mijn aangepaste functie voor celdefinitie te verspreiden.
De fout:
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>> | undefinedIk geef door aan een functie die bepaalt wat er teruggegeven moet worden
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
}
Dit geeft dan ofwel een cel terug die bewerkbaar is met een MUI-tekstveld of een div met een weergegeven waarde erin.
Hier is hoe de useEditableCell wordt gebruikt:
const editableCell = useEditableCell<BulkEditRow>(
setTableState,
getTableState
)
En vervolgens gebruikt binnen de kolomdefinities hier:
columnHelper.accessor('percentAustralia', {
id: 'percentAustralia',
header: () => RenderDefaultHeaderCell('% Australia'),
size: 12,
meta: {
validate: validatePercentageValueInTable,
},
...editableCell,
}),
Ik ben gewoon erg in de war waarom dit niet werkt als ik de kolom gewoon zo zou definiëren:
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}
/>
}
Het werkt prima. Elke hulp zou op prijs worden gesteld, hoewel alles wat ik doe met een doel en een specifiek gebruiksscenario in gedachten gebeurt, dus ik kan niets veranderen van wat ik doe.