I’m trying to implement a generic sort, which does 2 things.
It takes an array of type T
, that must have atleast one key with the specified type(string in this example), and an key from T
without specifying which key it in the function body is(imagine multiple properties with string values, i should be able to pass any of them). However I can’t quite get right. Either I end up with a type missmatch on the callers side(as example is showing). Or i end up with a function body that is of type any, such is the case if i replace [name: string]: name
with[name: string]: any
. Or I’am forced to name the specific key that i want to use for sorting(which I don’t really wanna do as that removes the reusability). as is the case for T extends {name: string}
This is what has been closest to working:
type User = {
name: string;
age: number
}
const myUsers: User[] = [{age: 32, name: "Foo"}]
type FilterBy<T, K> = {
[Key in keyof T as T[Key] extends K ? Key : never]: T[Key];
};
type InferValueFromArray<T extends any[]> = T extends Array<infer R>
? R
: never;
const sortingBy = <T extends { [name: string]: string }[], K extends keyof FilterBy<InferValueFromArray<T>, string>>(data: T, key: K) => {
return data.sort((a, b) => (a[key]).localeCompare(b[key]));
};
// this errors as Type 'number' is not assignable to type 'string'
const mySortedUsers = sortingBy(myUsers, 'name');
Here is the Typescript Playground Link