1

I am trying to achieve something like this:

interface Thing {
  id: string;
  price: number;
  test: number;
  other: { stuff: boolean };
}

type KeysWithValsOfType<T, V> = keyof {
  [P in keyof T as T[P] extends V ? P : never]: P;
};

const list = [
  {
    id: "1",
    price: 0,
    test: 2,
    other: { stuff: true },
  },
  {
    id: "12",
    price: 0,
    test: 2,
    other: { stuff: true },
  },
] as Array<Thing>;

function doSomeSortingThingWithStringProperties<T, K extends KeysWithValsOfType<T, string>>(
  list: T[],
  sortKey: K
) {
  list.sort((a, b) => (a[sortKey] < b[sortKey] ? 1 : -1));
}

doSomeSortingThingWithStringProperties(list, "id");      // <= ok
doSomeSortingThingWithStringProperties(list, "other");   // <= should be rejected by the compiler
console.log(list);

I get "Type 'K' cannot be used to index type 'T'.(2536)" for

a[sortKey]

I already checked : In TypeScript, how to get the keys of an object type whose values are of a given type? and How can I have TypeScript guarantee that a generic type has a property that implements a specific method?

Any suggestion to solve this in Typescript ?

Stéphane Gerber
  • 1,388
  • 1
  • 17
  • 30
  • 1
    You can constrain `T` to `Record` as well as constraining `K`, like [this](https://tsplay.dev/m3PKkW). See the answers to the linked questions for more information. – jcalz Jul 01 '22 at 18:08

0 Answers0