Search code examples
typescripttypescript-genericskeyof

In TypeScript how do I declare a generic with 2 arguments, where the first is a key of the second that returns a specific type?


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?


Solution

  • 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.