0

I'm looking to have a generic class like this one:

export abstract class Foo<ID extends keyof T, T> {
    bar(T t) {
        const s: string = t[ID];
    }
}

Obviously the code above can't infer the type of t[ID] and we're getting an implicit any. How can I enforce using generics T[ID] will be a string?

ronif
  • 695
  • 1
  • 6
  • 14
  • This isn't valid TypeScript, I assume you mean `T t` to be `t: T`, but where do you expect the value for `t[ID]` to come from? Is `id` an argument or class property? – Aaron Beall Apr 13 '18 at 18:00

1 Answers1

1

Your code doesn't compile so I changed it to something that will:

export abstract class Foo<ID extends string, T extends Record<ID, string>> {

  // add a property of type ID.
  constructor(public id: ID) { } 

  // change the Java-esque (T t) to (t: T)
  bar(t: T) {
    //use the id property to index t; can't use type ID at runtime
    const s: string = t[this.id]; 
  }

}

The way to enforce the relationship you want is: instead of constraining ID to keyof T, you constrain T to Record<ID, string> where Record<K, V> is a type from the standard TypeScript library describing any object with keys from K and values from V. Hope that helps. Good luck.

jcalz
  • 264,269
  • 27
  • 359
  • 360