Skip to content
Advertisement

convert react virtualized table from javascript to typescript – type issues

I am using this demo: https://codesandbox.io/s/react-virtualized-table-checbox-stackoverflow-rbl0v?fontsize=14&hidenavigation=1&theme=dark&file=/src/App.js And I put into my react project, and I am have problems with this piece of code:

 function _sortList({ sortBy, sortDirection }) {
    const newList = _.sortBy(list, [sortBy]);
    if (sortDirection === SortDirection.DESC) {
      newList.reverse();
    }
    return newList;
  }

  // eslint-disable-next-line no-shadow
  function _sort({ sortBy, sortDirection }) {
    setSortBy(sortBy);
    setSortDirection(sortDirection);
    setSortedList(_sortList({ sortBy, sortDirection }));
  }

The variable newList has a weird type (see error below) and won’t be accepted into the setSortedList function. I have tried building an interface, but I am not sure how to make newList be that type. Any tips for how to make this behave in typescript?

error

Argument of type '(number | { id: number; code: string; title: string; status: string; assigned: string; } | { <S extends { id: number; code: string; title: string; status: string; assigned: string; }>(callbackfn: (value: { id: number; code: string; title: string; status: string; assigned: string; }, index: number, array: { ...; }[])...' is not assignable to parameter of type 'SetStateAction<{ id: number; code: string; title: string; status: string; assigned: string; }[]>’.

  Type '(number | { id: number; code: string; title: string; status: string; assigned: string; } | { <S extends { id: number; code: string; title: string; status: string; assigned: string; }>(callbackfn: (value: { id: number; code: string; title: string; status: string; assigned: string; }, index: number, array: { ...; }[])...' is not assignable to type '{ id: number; code: string; title: string; status: string; assigned: string; }[]’.

    Type 'number | { id: number; code: string; title: string; status: string; assigned: string; } | { <S extends { id: number; code: string; title: string; status: string; assigned: string; }>(callbackfn: (value: { id: number; code: string; title: string; status: string; assigned: string; }, index: number, array: { ...; }[]) ...' is not assignable to type '{ id: number; code: string; title: string; status: string; assigned: string; }’.

      Type 'number' is not assignable to type '{ id: number; code: string; title: string; status: string; assigned: string; }'.

Advertisement

Answer

We have to declare the type for the two properties of the object which those functions take as their argument ({ sortBy, sortDirection }). If we were to call a sort function inline in the JSX then the arguments could be inferred from the component signature. But when we externalize a function like this we need to tell it what arguments to expect since the function itself has no awareness of where it is called.

Hovering over the sort attribute on Table shows the arguments:

(JSX attribute) sort?: (info: {
    sortBy: string;
    sortDirection: SortDirectionType;
}) => void

Since we use this in two places, let’s create a named alias for that object type:

interface SortInfo {
  sortBy: string;
  sortDirection: SortDirectionType;
}

Now we apply that type to our functions and everything works because the functions know the correct types for sortBy and sortDirection:

function _sort({ sortBy, sortDirection }: SortInfo) {
function _sortList({ sortBy, sortDirection }: SortInfo) {

Fully Converted Code

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement