Open Jontii opened 2 years ago
Only way I've found to get around this is to add a as string
or some other primitive type after info.getValue()
I'm having the same problem, any updates on this?
I m having same, so i fix with
const columns = useMemo<ColumnDef<Example, any>[]>
i don't know if this is the best way, but the typescript error should go away.
We skipped using columnDef, it still works as good and gives type help.
const columns = [
columnHelper.accessor("name", {
cell: (info) => info.getValue(),
}),
columnHelper.accessor("age", {
cell: (info) => info.getValue(),
}),
]
This is the way.
Thank you, it does work this way!
@tannerlinsley if you're saying @Jontii 's solution is the right way, you might want to change the Column Defs page in the docs to not use a column helper and a typed array. That is what you're saying right, either use one or the other?
If I understand it, if you use grouped columns like this example https://tanstack.com/table/v8/docs/examples/react/column-sizing then it is correct. If you are not using grouped columns, you shouldn't use it.
You should only be using the column helper and not pre-typing anything.
@tannerlinsley This is the first example in the Column Defs guide page:
// Define your row shape
type Person = {
firstName: string
lastName: string
age: number
visits: number
status: string
progress: number
}
const columnHelper = createColumnHelper<Person>()
// Make some columns!
const defaultColumns: ColumnDef<Person>[] = [ // <- Pre typed Array
// Display Column
columnHelper.display({ // <- While using column helper
id: 'actions',
cell: props => <RowActions row={props.row} />,
}),
// Grouping Column
columnHelper.group({
header: 'Name',
footer: props => props.column.id,
columns: [
// Accessor Column
columnHelper.accessor('firstName', {
cell: info => info.getValue(),
footer: props => props.column.id,
}),
// Accessor Column
columnHelper.accessor(row => row.lastName, {
id: 'lastName',
cell: info => info.getValue(),
header: () => <span>Last Name</span>,
footer: props => props.column.id,
}),
],
}),
// ...
It has the column array pre-typed and throws errors if any of these accessor columns are top level.
Yeah… we should fix that. On Oct 5, 2022 at 11:40 AM -0700, Chris Sandvik @.***>, wrote:
@tannerlinsley This is the first example in the Column Defs guide page: // Define your row shape type Person = { firstName: string lastName: string age: number visits: number status: string progress: number }
const columnHelper = createColumnHelper
() // Make some columns! const defaultColumns: ColumnDef
[] = [ // <- Pre typed Array // Display Column columnHelper.display({ // <- While using column helper id: 'actions', cell: props => , }), // Grouping Column columnHelper.group({ header: 'Name', footer: props => props.column.id, columns: [ // Accessor Column columnHelper.accessor('firstName', { cell: info => info.getValue(), footer: props => props.column.id, }), // Accessor Column columnHelper.accessor(row => row.lastName, { id: 'lastName', cell: info => info.getValue(), header: () => Last Name, footer: props => props.column.id, }), ], }), // ... It has the column array pre-typed and throws errors if any of these accessor columns are top level. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
Pre-typing would be helpful for public interfaces e.g. if we create a wrapper components with columns
and data
props. I am using this here right now:
interface DataTableProps {
// FIXME: Can we figure out something more type restrictive which actually works?
data: unknown[]
columns: ColumnDef<any, any>[];
}
That makes TypeScript "happy"... but I would prefer something more strict.
I guess I was looking for a typed CustomTableComponent
example which uses TanStack/Table underneath.
Pre-typing would be helpful for public interfaces e.g. if we create a wrapper components with
columns
anddata
props. I am using this here right now:
This! We're making a custom MyTableComponent
and expose columns
as prop that is pre-typed.
Pre-typing would be helpful for public interfaces e.g. if we create a wrapper components with
columns
anddata
props. I am using this here right now:interface DataTableProps { // FIXME: Can we figure out something more type restrictive which actually works? data: unknown[] columns: ColumnDef<any, any>[]; }
That makes TypeScript "happy"... but I would prefer something more strict.
I guess I was looking for a typed
CustomTableComponent
example which uses TanStack/Table underneath.
This makes typescript happy IF you allow use of any
which my codebase explicitly does not and which TS does not recommend
It becomes an issue when passing columns
to a component as a prop.
I am having the same issue here. Is there a way to avoid typing any
?
type Props<T> = {
data: T[];
columns: ColumnDef<T, any>[];
};
The EditableData example also uses React.useMemo<ColumnDef<Person>[]>(
, I guess that's not correct either?
@LoicKairon Glad I'm not the only one having this issue, I've done the same as you for now but would but nice to get that work properly.
Hey @tannerlinsley 👋 I there any update on "any
" type issue? It seems this issue is dead without being resolved for long time than I would expect. Should I open separated issue instead? We really love this library but having proper type instead of any
would really help us.
I am having the same issue here. Is there a way to avoid typing
any
?type Props<T> = { data: T[]; columns: ColumnDef<T, any>[]; };
I just encountered the same issue, which forced me to turn off no-explicit-any
.
Same use case as above, useTable is wrapped in a reuseable component that takes in columns
as a prop. Trying to use columHelper to create the definitions in the parent and it causes a typescript error.
Any update on this issue? Running into the same issue. My solution is to use any for the type and individually define the types for each cell:
type BillingDetails = {
id: number;
service: string;
talentName: string;
amount: number;
createdAt: string;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const columns: ColumnDef<BillingDetails, any>[] = [
columnHelper.accessor('service', {
id: 'service',
cell: (props) => props.getValue() as string,
header: 'Service',
enableSorting: false,
}),
columnHelper.accessor('talentName', {
id: 'talentName',
cell: (props) => props.getValue() as string,
header: 'Talent name',
enableSorting: false,
}),
columnHelper.accessor('amount', {
id: 'amount',
cell: (props) => props.getValue() as number,
header: 'Amount',
enableSorting: false,
}),
columnHelper.accessor('createdAt', {
id: 'createdAt',
cell: (props) => props.getValue() as string,
header: 'Created at',
enableSorting: false,
}),
]
Getting the same here, trying to convince our team to migrate to @tanstack/react-table and this is certainly getting in the way of that. I've defined columns as such: (nothing revolutionary)
const columnHelper = createColumnHelper<Coffee>();
const columns = [
columnHelper.accessor(data => data.id, {
id: 'id',
cell: info => info.getValue()
})
];
and have typed my generic table component as:
interface TableProps<T extends object> {
data: T[];
columns: ColumnDef<T>[];
}
export default function index<T extends object>({ columns, data }: TableProps<T>) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel()
});
(...)
But am then getting the following Type Error when passing my columns as a prop:
Property 'accessorFn' is missing in type 'ColumnDefBase<Coffee, number> & StringHeaderIdentifier' but required in type 'AccessorFnColumnDefBase<Coffee, unknown>'.ts(2322)
types.d.ts(83, 5): 'accessorFn' is declared here.
index.tsx(6, 3): The expected type comes from property 'columns' which is declared here on type 'IntrinsicAttributes & TableProps<Coffee>'
Any advice is appreciated
react-table version: 8.10.7 @types/react-table version: 7.7.18
Yeah getting same issue.
is there any solution for this. this still exists.
Waiting for the solution to this issue too.
yeah please i really require a solution for this.
Any progress here? Going to have to drop react-table if this isn't fixed, unfortunately.
Any progress here? Going to have to drop react-table if this isn't fixed, unfortunately.
That's very excessive, just put any for the second argument and it'll still work really well.
Can anyone provide a working vue-table example project that passes column info into a table component?
I'm using typescript and getting the following error no matter how I move the types around:
Uncaught (in promise) TypeError: columnDefs2 is undefined
Edit: An example that works even with the any
type would be awesome, I can't even get that to work.
for the time being I just removed the ColumnDef<Example>[]
from const columns: ColumnDef<Example>[] = [...]
and all worked just fine.
My generic table component have prop columns?: ColumnDef<T, any>[];
and it's also fine.
For me it seems to be anywhere that I'm returning a non-string from the accessor.
vs.
Having to cast everything to a string and back isn't the best.
still waiting for the official fix lol
Downgrade to 8.10.3 and it works.
This still happens only when you have multiple types on your object property
export type User = {
id: number;
name: string;
email: string;
role: "admin" | "member";
status: "active" | "pending";
};
// changing everything with type of string fixed the issue but whats the point of using typescript here
export type User = {
id: string;
name: string;
email: string;
role: string;
status: string;
};
@swernerx can you get some comments about this issue? Are you planning on fixing this? Please pay special attention to @cameronthrntn comment
Still facing this issue
Bump.
👀
Any update on this issue? What is the best workaround for this?
@RestartDK
I have been using the any
approach when defining my table props:
// table component
type Props<T> = {
data: T[];
columns: ColumnDef<T, any>[];
};
// when using the table component
const columnHelper = createColumnHelper<Vehicle>();
const columns = [
columnHelper.accessor("brand", {
header: "Marca",
}),
columnHelper.accessor("model", {
header: "Modello",
}),
]
const Testing = () => {
const vehicles = useVehicles();
return (
<Table data={vehicles} columns={columns} />
);
};
I haven't had any issues with inference or missing types so far.
@tanstack/react-table: "^8.15.3"
@4ndrs That's what I did previously, it's not ideal but it work's perfectly fine tbh.
This is my demo from what I created a tanstack table at my last role, see this
I wish people would stop spamming this thread 😆 There a good few answers here now, give them a go and see if any of them help you out.
@tannerlinsley and all the other maintainers/typescript wizards have done an incredible job with this library especially after it got a massive upgrade in ❤️ It's really difficult to get this sort stuff right so I'm sure in this particular case an "any" or "unknown" cast will do the trick everything else works great last time I checked.
I'm going to unsubscribe from this thread as I keep getting emails about it 🤣
Hello,
I am still facing the same issue on 8.15.0
and 8.15.3
.
I am following the shadcn example (Preview / Code)
Can't make it work with
const columns: ColumnDef<Task, any>[] = [
nor
const columns: ColumnDef<Task>[] = [
I am still getting the following error:
Type 'ColumnDef<Task, any>[]' is not assignable to type 'ColumnDef<unknown, any>[]'.
Type 'ColumnDef<Task, any>' is not assignable to type 'ColumnDef<unknown, any>'.
Type 'ColumnDefBase<Task, any> & StringHeaderIdentifier' is not assignable to type 'ColumnDef<unknown, any>'.
Type 'ColumnDefBase<Task, any> & StringHeaderIdentifier' is not assignable to type 'AccessorFnColumnDefBase<unknown, any> & IdIdentifier<unknown, any>'.
Property 'accessorFn' is missing in type 'ColumnDefBase<Task, any> & StringHeaderIdentifier' but required in type 'AccessorFnColumnDefBase<unknown, any>'.
The only workaround I use for now is:
columns: columns as ColumnDef<unknown>[],
Somebody help please. I added custom variable to columnDef and typescript is not recognizing it I don't know how to fix it. This is the error: Property 'category' does not exist on type 'ColumnDef<TData, unknown>'. Property 'category' does not exist on type 'ColumnDefBase<TData, unknown> & StringHeaderIdentifier'
import { Button } from './button';
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
} from './dropdown-menu';
import { PaginationSection } from './pagination-section';
import {
flexRender,
ColumnFiltersState,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
useReactTable,
ColumnDef,
} from '@tanstack/react-table';
import { ChevronDown } from 'lucide-react';
import { useRouter, useSearchParams } from 'next/navigation';
import queryString from 'query-string';
import { useEffect, useRef, useState } from 'react';
import { useDebounce } from 'use-debounce';
import { Input } from '@/components/ui/input';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
data: TData[];
total: number;
onRowClick?: [keyof TData, (value: TData[keyof TData]) => void];
}
export function DataTable<TData, TValue>({
columns,
data,
total,
onRowClick,
}: DataTableProps<TData, TValue>) {
const router = useRouter();
const searchParams = useSearchParams();
const paramsObject = Object.fromEntries(searchParams);
const filtersString = queryString.stringify(
Object.fromEntries(
Object.entries(paramsObject).filter(([key, value]) => key !== 'search')
)
);
const initialRender = useRef(true);
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const [isMounted, setIsMounted] = useState(false);
const [text, setText] = useState(paramsObject.search);
const [searchQuery] = useDebounce(text, 750);
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onColumnFiltersChange: setColumnFilters,
getFilteredRowModel: getFilteredRowModel(),
state: {
columnFilters,
},
enableHiding: true,
initialState: {
pagination: { pageSize: parseInt(paramsObject.limit || '10') },
},
});
useEffect(() => {
if (!initialRender.current) {
initialRender.current = true;
return;
}
if (searchQuery) {
router.push(`?${filtersString}&search=${searchQuery}`);
} else if (searchQuery === '') router.push(`?${filtersString}`);
}, [searchQuery]);
useEffect(() => {
setIsMounted(true);
}, [isMounted]);
if (!isMounted) return null;
return (
<div className="flex flex-col w-full overflow-x-auto">
<div className="w-full flex items-center justify-between py-4">
...
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="ml-auto">
Columns <ChevronDown className="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{table
.getAllColumns()
.filter((column) => column.getCanHide())
.map((column) => (
<DropdownMenuCheckboxItem
key={column.id}
className="capitalize"
checked={column.getIsVisible()}
onCheckedChange={(value) => column.toggleVisibility(!!value)}
>
{column.id}
</DropdownMenuCheckboxItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</div>
<div>
<Button
variant={'outline'}
onClick={() => {
table
.getAllColumns()
.filter((column) => column.getCanHide())
.forEach((column) => {
if (column.columnDef.category === 'ATTACKING') {
column.toggleVisibility(!column.getIsVisible());
}
});
}}
>
Attacking
</Button>
...
</div>
</div>
);
}
I'm also trying to pass columns
into a custom Table component that requires a tableLink
field in the data.
interface DataTableProps<LinkableRows extends boolean | undefined, TData, TValue> {
columns: LinkableRows extends true
? ColumnDef<TData & TableLink, TValue>[]
: ColumnDef<TData, TValue>[];
data: LinkableRows extends true ? (TData & TableLink)[] : TData[];
linkRows?: LinkableRows;
}
type DataTableWithLinksProps<TData, TValue> = DataTableProps<true, TData, TValue>;
type DataTableWithoutLinksProps<TData, TValue> = DataTableProps<false, TData, TValue>;
const export function CustomTable<TData, TValue>({
columns,
data,
linkRows
}: DataTableWithLinksProps<TData, TValue> | DataTableWithoutLinksProps<TData, TValue>) {
const table = useReactTable({
columns, // accessorFn error here
data,
...
});
// ...return table element that navigates to `row.original.tableLink` on
// row click if linkRows is true
}
This would work if columns
was defined as just ColumnDef<TData, TValue>
. The TS Error occurs when adding the intersection with { tableLink: string }
to the ColumnDef
.
Strangely, if I replace the union props type definition for the component params, with either DataTableWithLinkProps
only or DataTableWithoutLinksProps
only, the error also goes away...
Any solution/ideas?
Any updates how to fix correct?
Hello, I am still facing the same issue on
8.15.0
and8.15.3
. I am following the shadcn example (Preview / Code) Can't make it work withconst columns: ColumnDef<Task, any>[] = [
nor
const columns: ColumnDef<Task>[] = [
I am still getting the following error:
Type 'ColumnDef<Task, any>[]' is not assignable to type 'ColumnDef<unknown, any>[]'. Type 'ColumnDef<Task, any>' is not assignable to type 'ColumnDef<unknown, any>'. Type 'ColumnDefBase<Task, any> & StringHeaderIdentifier' is not assignable to type 'ColumnDef<unknown, any>'. Type 'ColumnDefBase<Task, any> & StringHeaderIdentifier' is not assignable to type 'AccessorFnColumnDefBase<unknown, any> & IdIdentifier<unknown, any>'. Property 'accessorFn' is missing in type 'ColumnDefBase<Task, any> & StringHeaderIdentifier' but required in type 'AccessorFnColumnDefBase<unknown, any>'.
The only workaround I use for now is:
columns: columns as ColumnDef<unknown>[],
I am getting the below error while using like this.
Type 'ColumnDef
Any updates? Two years have already passed
I thought I was going crazy, followed the docs to a T, defined some straightforward columns, but can't make a generic table component and pass the columns to them with type safety for the life of me. Glad to see I'm not alone I guess.
I had something similar to this when I tried to pass the columns
and define them between components
Type 'PostColumn[]' is not assignable to type 'ColumnDef<Record<string, unknown>, unknown>[]'.
Type 'PostColumn' is not assignable to type 'ColumnDef<Record<string, unknown>, unknown>'.
Type 'ColumnDefBase<Post, unknown> & StringHeaderIdentifier' is not assignable to type 'ColumnDef<Record<string, unknown>, unknown>'.
Type 'ColumnDefBase<Post, unknown> & StringHeaderIdentifier' is not assignable to type 'AccessorFnColumnDefBase<Record<string, unknown>, unknown> & IdIdentifier<Record<string, unknown>, unknown>'.
Property 'accessorFn' is missing in type 'ColumnDefBase<Post, unknown> & StringHeaderIdentifier' but required in type 'AccessorFnColumnDefBase<Record<string, unknown>, unknown>'.ts(2322)
types.d.ts(98, 5): 'accessorFn' is declared here.
index.jsx(26, 2): The expected type comes from property 'columns' which is declared here on type 'IntrinsicAttributes & ApiDataTableStoreProps<"posts.getMany", Record<string, unknown>, unknown>'
For some reason it worked with me when I changed the type that will be used on the ColumnDef
from being defined by interface
to be defined by type, for example:
From
interface Post {
id: string;
title: string;
content: string;
}
To
type Post = {
id: string;
title: string;
content: string;
}
And I have no idea of why and how
Describe the bug
Looking at the examples and docs I expect this to correctly type my columns for me. Instead I get a large error with this code:
Am I doing something wrong here?
Regards Jonathan
Your minimal, reproducible example
https://codesandbox.io/s/typescript-playground-export-forked-iqm265?file=/index.tsx
Steps to reproduce
Expected behavior
I expected the Columdef to correctly type my columns.
How often does this bug happen?
Every time
Screenshots or Videos
Platform
Mac OS
react-table version
v8.5.13
TypeScript version
v4.8.2
Additional context
No response
Terms & Code of Conduct