Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript w/ React - Argument of type 'string' is not assignable to parameter of type 'keyof T'

I have a sorting function built with TypeScript and React Hooks that I am having some issues with.

Specifically I am receiving an error stating:

Argument of type 'string' is not assignable to parameter of type 'keyof T'.
  Type 'string' is not assignable to type 'never'.ts(2345)

You can see the sorting function and how I am attempting to test it here on CodeSandbox

I am not really sure where the never would be coming from.

Any helpful links would be appreciated.

I will try to remove some of the unnecessary code but I have a bad habit of removing code which then changes the context (when using TypeScript) which results in a answer that may not be as helpful for my use case.

import { useState, useEffect } from "react";

export function SortByKey<T extends object>({
  data,
  sortKey
}: {
  data: T[];
  sortKey: keyof T;
}) {
  let sortable = [...data];

  sortable.sort((a: T, b: T) => {
    if (a[sortKey] < b[sortKey]) {
      return -1;
    }
    if (a[sortKey] > b[sortKey]) {
      return 1;
    }
    return 0;
  });

  return sortable;
}

export default function App<T extends object>({ data }: { data: T[] }) {
  const [sortedData, setSortedData] = useState(data);

  const sortKeys: string[] = Object.keys(data[0]);

  function handleClick(sortKey: keyof T) {
    setSortedData(SortByKey({ data, sortKey }));
  }

  useEffect(() => {
    console.log(sortedData);
  }, [sortedData]);

  return (
    <div>
      {sortKeys.map((sortKey) => {
        return (
          <button key={sortKey} onClick={() => handleClick(sortKey)}>
            {sortKey}
          </button>
        );
      })}
    </div>
  );
}
like image 278
FamousAv8er Avatar asked Sep 03 '25 01:09

FamousAv8er


1 Answers

Replace object in "App<T extends object>" with Record<string, any>, ie:

export default function App<T extends Record<string, any>>({ data }: { data: T[] }) {

this will make handleClick of button.onClick stop throwing errors.

Why: because when you ask for keys of object, they are empty by default, and there is no index signature as well.

like image 194
c69 Avatar answered Sep 10 '25 05:09

c69