Hi all,
I'd like to start by saying thank you to all the maintainers and contributors of this package 馃挴 and also apologies for not using the issue template format, wasn't quite sure if this was a bug or a feature request.
I've been trialling the v7 branch, and overall its really really impressive 馃檶 The only part that seemed a little ... lacking was the Typescript types. This was not a huge issue, as I was able to create my own types file that the compiler merges with the types provided by react-table (using declaration merging)
I noticed that beta 12 has recently been released, and I updated (from beta 10). Unfortunately, it seems that the situation has somewhat worsened from a developer experience perspective. I'm assuming the changes were made in order to better handle the fact that any number of plugin hooks might be specified by a user. However, these changes seem to have come at the cost of requiring users to include a custom types file in their projects (which is a little unusual, even for Typescript projects).
In an ideal world, it'd be great to see react-table written natively in Typescript to avoid situations where the code and types are not in sync, but I do understand that might not be what the maintainers/contributors want. That said, the procedure in beta 12 seems like it could be improved, and I'm happy to help 馃槃 I'm including my additions to the types file from beta 10 that mostly fixed the plugin issues, as well as adding a few other missing types. There are some definite improvements in the beta 12 types, so it'd be good to see if we can find some middle ground.
import {
Row,
TableInstance,
TableOptions,
useGroupBy,
useFilters,
useSortBy,
useExpanded,
usePagination,
useRowSelect,
useRowState,
useColumnOrder,
useBlockLayout,
useAbsoluteLayout,
useResizeColumns,
Column,
} from "react-table";
declare module 'react-table' {
export interface TableInstance<D = {}> extends TableOptions<D> {
getTableBodyProps: (userProps?: any) => any
selectedFlatRows: Row<D>[]
}
export interface HeaderColumn<D> {
disableFilters?: boolean;
}
export interface EnhancedColumn<D>
extends Omit<Column<D>, 'columns'>,
TableInstance<D> {
canFilter?: boolean
}
export interface UsePaginationValues<D = {}> {
pageOptions: number[]
}
export type Plugin<D> = useGroupBy<D> |
useFilters<D> |
useSortBy<D> |
useExpanded<D> |
usePagination<D> |
useRowSelect<D> |
useRowState<D> |
useColumnOrder<D> |
useBlockLayout<D> |
useAbsoluteLayout<D> |
useResizeColumns<D>
export function useTable<D = {}, P = Plugin<D>>(
props: TableOptions<D>,
...plugins: P[]
): TableInstance<D> & ReturnType<typeof P>
export function useRowSelect<D = {}>(
props: TableOptions<D>
): TableOptions<D>
}
I'm confused as to what you're saying is missing/worse?
canFilter, disableFilter are still in a PR. I added getTableBodyProps and can't remember if selectedFlatRows was added off the top of my head. (I'm away from my computer)
Hi @stramel, the part I was referring to as worsened is the instructions in TYPESCRIPT.md, specifically the idea of copying a types file from react-table into my project.
I was unaware that there were PRs for the missing types, thanks for letting me know 馃榾
I found this file here: https://gist.github.com/Grsmto/1ac3a7ddb8ad8288660784a37bff1798
// Type definitions for react-table 7
// Project: https://github.com/tannerlinsley/react-table#readme
// Definitions by: Adrien Denat <https://github.com/grsmto>
// Artem Berdyshev <https://github.com/berdyshev>
// Christian Murphy <https://github.com/ChristianMurphy>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 3.0
declare module 'react-table' {
import { Dispatch, SetStateAction, ReactNode } from 'react'
export interface Cell<D> {
render: (type: string) => any
getCellProps: () => any
column: Column<D>
row: Row<D>
state: any
value: any
}
export interface Row<D> {
index: number
cells: Cell<D>[]
getRowProps: () => any
original: any
}
export interface HeaderColumn<D, A extends keyof D = never> {
/**
* This string/function is used to build the data model for your column.
*/
accessor: A | ((originalRow: D) => string)
Header?: string | ((props: TableInstance<D>) => ReactNode)
Filter?: string | ((props: TableInstance<D>) => ReactNode)
Cell?: string | ((cell: Cell<D>) => ReactNode)
/**
* This is the unique ID for the column. It is used by reference in things like sorting, grouping, filtering etc.
*/
id?: string | number
minWidth?: string | number
maxWidth?: string | number
width?: string | number
canSortBy?: boolean
sortByFn?: (a: any, b: any, desc: boolean) => 0 | 1 | -1
defaultSortDesc?: boolean
}
export interface Column<D, A extends keyof D = never> extends HeaderColumn<D, A> {
id: string | number
}
export type Page<D> = Row<D>[]
export interface EnhancedColumn<D, A extends keyof D = never> extends Column<D, A> {
render: (type: string) => any
getHeaderProps: (userProps?: any) => any
getSortByToggleProps: (userProps?: any) => any
sorted: boolean
sortedDesc: boolean
sortedIndex: number
}
export type HeaderGroup<D, A extends keyof D = never> = {
headers: EnhancedColumn<D, A>[]
getRowProps: (userProps?: any) => any
}
export interface Hooks<D> {
beforeRender: []
columns: []
headerGroups: []
headers: []
rows: Row<D>[]
row: []
renderableRows: []
getTableProps: []
getRowProps: []
getHeaderRowProps: []
getHeaderProps: []
getCellProps: []
}
export interface TableInstance<D>
extends TableOptions<D>,
UseRowsValues<D>,
UseFiltersValues,
UsePaginationValues<D>,
UseColumnsValues<D> {
hooks: Hooks<D>
rows: Row<D>[]
columns: EnhancedColumn<D>[]
getTableProps: (userProps?: any) => any
getRowProps: (userProps?: any) => any
prepareRow: (row: Row<D>) => any
getSelectRowToggleProps: (userProps?: any) => any
toggleSelectAll: (forcedState: boolean) => any
}
export interface TableOptions<D> {
data: D[]
columns: HeaderColumn<D>[]
state?: [any, Dispatch<SetStateAction<any>>]
debug?: boolean
sortByFn?: (a: any, b: any, desc: boolean) => 0 | 1 | -1
manualSorting?: boolean
disableSorting?: boolean
defaultSortDesc?: boolean
disableMultiSort?: boolean
}
export interface RowsProps {
subRowsKey: string
}
export interface FiltersProps {
filterFn: () => void
manualFilters: boolean
disableFilters: boolean
setFilter: () => any
setAllFilters: () => any
}
export interface UsePaginationValues<D> {
nextPage: () => any
previousPage: () => any
setPageSize: (size: number) => any
gotoPage: (page: number) => any
canPreviousPage: boolean
canNextPage: boolean
page: Page<D>
pageOptions: []
}
export interface UseRowsValues<D> {
rows: Row<D>[]
}
export interface UseColumnsValues<D> {
columns: EnhancedColumn<D>[]
headerGroups: HeaderGroup<D>[]
headers: EnhancedColumn<D>[]
}
export interface UseFiltersValues {
setFilter: () => any
setAllFilters: () => any
}
export function useTable<D>(props: TableOptions<D>, ...plugins: any[]): TableInstance<D>
export function useColumns<D>(props: TableOptions<D>): TableOptions<D> & UseColumnsValues<D>
export function useRows<D>(props: TableOptions<D>): TableOptions<D> & UseRowsValues<D>
export function useFilters<D>(
props: TableOptions<D>,
): TableOptions<D> & {
rows: Row<D>[]
}
export function useSortBy<D>(
props: TableOptions<D>,
): TableOptions<D> & {
rows: Row<D>[]
}
export function useGroupBy<D>(props: TableOptions<D>): TableOptions<D> & { rows: Row<D>[] }
export function usePagination<D>(props: TableOptions<D>): UsePaginationValues<D>
export function useFlexLayout<D>(props: TableOptions<D>): TableOptions<D>
export function useExpanded<D>(
props: TableOptions<D>,
): TableOptions<D> & {
toggleExpandedByPath: () => any
expandedDepth: []
rows: []
}
export function useTableState(
initialState?: any,
overriddenState?: any,
options?: {
reducer?: (oldState: any, newState: any, type: string) => any
useState?: [any, Dispatch<SetStateAction<any>>]
},
): any
export const actions: any
}
@hassankhan That document is very new and still needs some revisions. We don't generally copying types except for maybe to use in an example or as a starting point. I'm still not sure what you are saying has regressed as the typescript documentation is brand new, I don't see how it could regress?
@tsujp That gist is very out of date and incompatible with the types that are going to be supported.
Beta 12 doesn't work as-is with Types though, why can't the repo be redone with Typescript inline instead of separation of concerns that is currently the focus? Isn't this the perfect time?
I'd love to help out if I wasn't so average at Typescript, I only just started using it two months ago unfortunately.
What exactly do you mean by "separation of concerns"? Do you mean that the types don't just lump in every hooks behavior? How do you deal with external hooks? How do you deal with hooks that are standard, but aren't included in the configuration of the table? These are all separate right now so that each user can tailor the interface so match what's supported.
I'll admit that this is a bit awkward, I don't think that anyone is particularly happy with it, but until we get a better solution that works for those use cases, I don't really see an alternative.
As a separate point, the interface is huge and changing (it is a beta after all), it's been very easy to miss stuff, so yes, there are apis that have been missing. But again, they can easily be added locally (using the same declaration merging technique) until they get added to the main types.
I'm not saying that we don't want this to be easier, we do, it's just not obvious what the right solution is and so we went with something that works until we can get something better.
Chiming in here with a typing issue. I'm getting Property 'getSortByToggleProps' does not exist on type 'ColumnInstance<any>'. when trying to implement sortable columns in TypeScript. I've essentially copy/pasting the sorting example to get started here.
react-table version: 7.0.0-beta.12

CodeSandbox here: https://codesandbox.io/s/react-table-beta-12-typings-xculv
@kpollich I had the same issue. What you have to do, is to copy the file react-table-config.d.ts, inside a directory (I recommend copying it inside the directory as your table component).
Then remove the interface you do not need or the extends you won't use.
Everything is explained here : https://github.com/tannerlinsley/react-table/blob/master/TYPESCRIPT.md
I hope this helps 馃槂
The types at https://github.com/tannerlinsley/react-table/blob/master/TYPESCRIPT.md do not function properly.
prepareRow() is of type void and so the statement prepareRow(row) || ... is invalid. An expression of type void cannot be checked for truthiness. Attempting to workaround this by turning it into (prepareRow(row), ...) is also invalid.
I haven't been able to use this library with the types present in the repo yet.
EDIT:
It seems I had the syntax wrong, a working example would be
{rows.map(
(row, i) => (
(prepareRow(row), (
<tr {...row.getRowProps()}>
// ... do stuff
</tr>
)))
)}
Instead of
{rows.map(
(row, i) =>
prepareRow(row) || (
<tr {...row.getRowProps()}>
// ... do stuff
</tr>
)
)}
yeah, the problem is that the examples all do prepareRow() || ..., but prepareRow is actually void, you can check the code, it has no return.
That said, while it's a bit misleading, it is valid javascript so perhaps we should have defined prepareRow as returning undefined. It's not exactly what's going on, but it would have keep the usage in the examples working in typescript.
Indeed I was just a bit thrown off as I am newly getting into TypeScript. All the examples are Javascript too so there will always be some differences I suppose. It's no bother now I think as the example in my previous comment is valid TypeScript as per:
I'm specifically seeing a couple other bugs in the beta-12 types:
UseRowSelectState, the selectedRows field is wrong. The code has a selectedRowPaths fieldUseRowSelectInstanceProps, the toggleRowSelected method appears to expect an array that it can call .join() on, not a single stringMy hacky local fixes in our types customization file:
// FIX The R-T type claims this is selectedRows, not selectedRowPaths
export interface UseRowSelectState<D extends object> {
selectedRowPaths: IdType<D>[];
}
// FIX The R-T type for toggleRowSelected says it takes a string, not an array
export type UseRowSelectInstancePropsFixed<D extends object> = Omit<
UseRowSelectInstanceProps,
"toggleRowSelected"
> & {
toggleRowSelected: (rowPath: (string | number)[], set?: boolean) => void;
};
a) that's exactly how I fix these in my project.
b) the selectedRowPaths change actually matches what's in master, by not shipped yet.
c) the toggleRowSelected fix is new to me and looks like an unreported bug. I'll try to keep track of it.
I'm getting the following error:
Object literal may only specify known properties, and 'disableMultiSort' does not exist in type 'TableOptions<object>'.
Same for selectedFlatRows, isAllRowsSelected atm, no type definitions. @hassankhan can you link here the PRs that have these kind of missing types please?
Same for
selectedFlatRows,isAllRowsSelectedatm, no type definitions. @hassankhan can you link here the PRs that have these kind of missing types please?
Look on UseRowSelectInstanceProps for those two, they are there.
You mean here @ggascoigne ? https://github.com/tannerlinsley/react-table/blob/master/index.d.ts#L452
My index.d.ts is a bit different from that 馃

I'm guessing that you're using beta.12 or earlier, that definition was added for beta.13 or later.
Yap, that's it @ggascoigne thanks! 馃憤
I'm using beta.12 and this is how I include plugins to react-table types, it's really simple:
declare module 'react-table' {
interface Row<D> extends UseExpandedRowProps<D> { }
interface Column<D extends object = {}> extends UseSortByColumnOptions<D> {}
interface ColumnInstance<D extends object = {}> extends UseSortByColumnProps<D> { }
interface TableOptions<D extends object = {}> extends UseSortByOptions<D> { }
}
Using beta.20 and getting this error:
Object literal may only specify known properties, and 'getResetPageDeps' does not exist in type 'TableOptions<any>'.ts(2345)
It looks like that option is under UsePaginationOptions instead, but the CodeSandbox examples have it inside useTable.
My useTable instantiation:
const {
getTableProps,
getTableBodyProps,
headerGroups,
prepareRow,
page,
canPreviousPage,
canNextPage,
pageCount,
gotoPage,
nextPage,
previousPage,
setPageSize,
state: { pageIndex, pageSize },
} = useTable(
{
columns,
data,
defaultColumn,
getResetPageDeps: skipPageReset ? false : undefined,
onUpdateLocations,
},
usePagination,
);
Yeah, there was a significant amount of refactoring in beta.20. Types are most definitely out of sync.
This has been itching me for a last few weeks and I think I've decided I want to move the types out of this repo and into the Definitely Typed repo. Until React Table is inevitably rewritten in Typescript itself, I would like to move the discussions/issues/expectations around types over to DT.
I'm not sure what is required here, but I'm assuming it should be pretty simple to PR the types over to DT. As soon as that's done, I have no problem adding a dependency on the external types.
Thanks for all of your work guys. Keep it up, please! There are a lot of TS users that are benefiting from this :)
I'll admit that I'm in two minds about this. Obviously they belong there in the long run, but as long as the interface keeps changing in some pretty substantial ways, there's some convenience in having them here. Also, you don't work in typescript (and that's OK), but how do you hope to understand the api issues around typing this api if you aren't part of that conversation.
Yeah, and honestly, the api could be changing even more in the coming days, but I don't see any more convenience in having them colocated. As of today in beta, they will likely continue to get out-of-date as we refactor, write tests, move towards an RC, etc, and the last thing I want for people is a false sense of security to see that there are "native" looking types in the repo that don't actually have any guarantees around them. With that said, I understand that "changes" and "refactors" sound scary to after-the-fact type-defs, but at the same time, I don't plan on turning the library upside down for those same type-defs until I'm ready to go all-in on TS. For now, I hope I would still be including in the discussions around types with a simple @tannerlinsley 馃槂.
Understandable. One thing that I do notice looking at the definitely typed docs, it will be hard to publish types for the v7 betas until the version number follows semantic versioning, at least unless I'm missing something there.
Yeah, I'm not totally versed in how DT works with prereleases and tags. As of today though, the default install for react-table is now v7 (it was actually a CI accident) and I just decided to keep it (still beta though, like Fortnite! 馃槈 ).
As of right now today, the API still has a lot of non-type related things that will be changing under the hood, including refactors of the internal "instance" architecture, footer support, global filters, etc, then not to mention tests... lots of them.
Porting my comment to here to continue the discussion. https://github.com/tannerlinsley/react-table/pull/1534#issuecomment-560533319
So I have felt some burnout on trying to keep up with the definitions with lots of rework being thrown in and no chance to get the types updated before the release. Essentially by having them in the repo, it _should_ be part of the release process to update the types before a release is cut.
I second @ggascoigne, and think that without some major API changes, that converting to typescript/coming up with a good external typescript definition, will be very difficult.
Personally, I think the easiest solution would be to rewrite it with typescript. This would allow us to see pain points as they come up and rework the API to allow nice typings.
@tannerlinsley I think your last change broke my app. I'm getting node_modules/react-table/index.d.ts' is not a module. Any idea?
@bnbarak I would open a new issue with more info like the version you're using, etc. This is more of a long-term discussion on types.
FYI I posted a PR with the latest types to DT https://github.com/DefinitelyTyped/DefinitelyTyped/pull/40816 - note that these still require declaration merging but at least this gives us a place to discuss things.
fwiw i would rather see types in this repo and kept up to date, esp. once 7 goes stable. Having them here means you can expect/request PRs to include the relevant typing updates, and they should be up to date (and tested in CI, I could maybe contribute here) for stable releases.
I'm pretty understanding that prereleases might have the definitions slip, but for stable releases there shouldn't be a huge maintenance burden here, should there?
Sincerely,
just some guy who uses this great library.
@bnbarak I've had to pin react-table 6.10.3 and @types/react-able 6.8.3 to fix that error. We're waiting until v7 is stable to upgrade our table implementation, so will probably just keep those versions pinned for now.
FWIW, I can say that as a Redux maintainer, even types for a tiny and very stable lib _can_ be a "maintenance burden". I talked about my experience in my post Learning and Using TypeScript as an App Dev and a Library Maintainer. For a brand new lib that has some _much_ more complex behavior, I can easily see that being much more of a distraction.
There's strong and valid arguments for all 3 scenarios (keep types in DT, keep types in repo, rewrite lib in TS entirely). Since Tanner's the maintainer, he gets to pick what approach he wants.
Agreed. Even if they were 100% community driven, there is still a fair amount of "chores" work. I'm not saying it's hard by any means, but it is noise that ends up being a distraction (even in the short time the typings were in this repo, the conversations, PRs, and issues around them were already pretty distracting for me). At this point, it's just a countermeasure to keep myself pumped about the project and excited to work on it.
@kpollich I had the same issue. What you have to do, is to copy the file
react-table-config.d.ts, inside a directory (I recommend copying it inside the directory as your table component).
Then remove the interface you do not need or the extends you won't use.Everything is explained here : https://github.com/tannerlinsley/react-table/blob/master/TYPESCRIPT.md
I hope this helps 馃槂
Thanks! This solution works, will this be a one time fix or it requires regular update that depends on definitely typed / react table ?
Hey typescript developers, would you donate typescript example please... :heart:
Agreed. I'm still getting this type error using typescript ([email protected] & type version v7.0.17)

I am also using useSortBy
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable(
{
columns,
data,
},
useSortBy
);
Note: The functionality works fine, just getting a type error
@bsell93 make sure to include sort options in your types..
@lishine Found an example here:
https://github.com/tannerlinsley/react-table/pull/1585/files/d80305deb5d4653c49222f750941d78a9b9da9a9
I personally solved this issue by using the interface defined in the above link
interface TableColumn<D extends object = {}>
extends ColumnInstance<D>,
UseSortByColumnProps<D>,
UseResizeColumnsColumnProps<D>,
UseFiltersColumnProps<D> {}
and casting the column like so:
const column = (c as unknown) as TableColumn<object>;
@gargroh I don't follow. The type of the column is inferred based on the type definition. Are you suggesting I cast like I did above?
Casting should not be needed, this example would help https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-table#example-type-file
@gargroh that did the trick!
Although it does seem silly to have to re-declare/define the interfaces in the module. My first thought is that the type would change when I added useSortBy.
Either way, thanks for your help!
Casting should not be needed, this example would help https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-table#example-type-file
maybe it's an issue with v7.6.0 (types v7.0.24) but getting errors on all of those definitions in react-table-config.d.ts:
All declarations of 'ColumnInstance' must have identical type parameters. ts(2428)
For anyone else facing issues after copy/pasting the react-table-config.d.ts, this CodeSandbox (referenced here) was super useful.
It's probably worth pointing out that that there is a readme for the typescript types https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-table/Readme.md which also includes that react-table-config.d.ts.
Sadly there's no good standard place to document types that live outside of a project and that was the best that we came up with. Easy to miss though :(
to give my 2 cents:
transition to typescript is not that hard as it seems. If you setup the tooling right, you can just rename js(x) files to ts(x), start to annotate some functions one by one, without rewriting the whole library. E.g. you can just annotate the files you touch.
it will eventually fall into place like a jigsaw (and you will usually find a bug or two!). 馃З This is especially true with hooks which are just functions, and functions are simple to annotate.
and all of sudden your public api is properly annotated 馃槂
I hear you, and I even tried to do that at the start of 2020. However, I quickly learned a few things:
anys and unknowns. This is fine, but not in the long run. At some point, the work/time will be better spent in a rewrite.With all of that said, you'll be happy to know that I'm currently writing v8 natively in TypeScript. I assure you, it's a beast, but it's also awesome. Take it from me, with what I know about the internals and current API in v7, there's no way to backport accurate types to v7 that will even come close to v8.
I hear you, and I even tried to do that at the start of 2020. However, I quickly learned a few things:
- Incrementally adding TS to a JS project like you said is easy to start, but quickly results in a massive amount of
anys andunknowns. This is fine, but not in the long run. At some point, the work/time will be better spent in a rewrite.- With public gradual migration, it's inevitable that you will eventually have to make breaking changes to get rid of the untypable dynamisms in the library to get full TS intellisense and holistically correct types. This isn't a very good experience to have a public api that is always slowly, but constantly, breaking.
- TypeScript is simple, but not easy. A library like this requires a massive amount of generics, a highly sophisticated plugin system with multiple plugin points (22+ actually) and a very rich I/O model that permeates just about every corner of the library.
With all of that said, you'll be happy to know that I'm currently writing v8 natively in TypeScript. I assure you, it's a beast, but it's also awesome. Take it from me, with what I know about the internals and current API in v7, there's no way to backport accurate types to v7 that will even come close to v8.
that's good to hear, so we'll wait for v8 to adopt!
@ggascoigne Are there any simple typescript table examples with sorting and a filter?
I went through the getting started guide in js, then I found a simple typescript example, but then I tried to add filtering from what I saw in https://github.com/ggascoigne/react-table-example and haven't gotten it to work. More simple typescript examples would help a lot.
@tannerlinsley Any target for when v8 would be ready?
@AgustinBrst
Thanks alot, It solved my problem
Most helpful comment
Chiming in here with a typing issue. I'm getting
Property 'getSortByToggleProps' does not exist on type 'ColumnInstance<any>'.when trying to implement sortable columns in TypeScript. I've essentially copy/pasting the sorting example to get started here.react-tableversion: 7.0.0-beta.12CodeSandbox here: https://codesandbox.io/s/react-table-beta-12-typings-xculv