Reputation: 2965
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>
);
}
Upvotes: 4
Views: 4770
Reputation: 21507
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.
Upvotes: 4
Reputation: 2358
You need to cast sortKeys
to (keyof T)[]
:
const sortKeys = Object.keys(data[0]) as (keyof T)[];
But it doesn't look like a very useful type.
Upvotes: 2