Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't typescript infer the type of `T[key of T]` for type parameter `T` here?

Tags:

typescript

I'm trying to write a generic class that is passed a key key corresponding to a key of one of a set of known interfaces on construction and that can later be passed an object thing and type-safely access thing[key]. This is what I've got:

interface AB {
  a: string
  b: number
}

interface BC {
  b: number
  c: Date
}

type ABC = AB | BC

class Getter<T extends ABC> {
  key: keyof T;

  constructor(key: keyof T) {
    this.key = key;
  }

  get(thing: T): string {
    const value = thing[this.key];
    return value.toString();
  }
  
}

const getter = new Getter<AB>('b');

Playground Link

Here, I'd expect Typescript to infer that because T extends ABC that T[keyof T] = AB[keyof AB] | BC [keyof BC] = string | number | date. However, it seems to get stuck at T[keyof T]. Even adding an as AB[keyof AB] | BC[keyof BC] to that line doesn't fix it, I need as unknown as AB[keyof AB] | BC[keyof BC]! Is there any way to get this working without that line?

Also, is there any way I could parameterize over the value of key as a type instead of parameterizing over the type of thing?

like image 793
Joel Newman Avatar asked Dec 19 '25 08:12

Joel Newman


1 Answers

When T extends ABC, it can have many other properties and types. Which can therefore not have .toString() method.

type G = {
  a: string;
  b: number;
  hello: undefined;
};

const g = new Getter<G, keyof G>("hello");

g.get({
  a: "a",
  b: 1,
  hello: undefined
}); // undefined does not have .toString() method

Playground Link

like image 168
ghybs Avatar answered Dec 21 '25 04:12

ghybs



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!