Ian Bytchek
Ian Bytchek

Reputation: 9085

Generic interface with index-type property and method

Is there a way in TypeScript to declare the following interface using index types and exactly one generic type, where map method would accept value of the same type as T's key instead of any?

interface Foo<T> {
    key: keyof T;
    map: (value: any) => any;
}

Again, the interface needs to accept only one generic type. The following is a possible solution, but does't solve this problem since takes two generic types:

interface Foo<T, K extends keyof T> {
    key: K;
    map: (value: T[K]) => any;
}

Upvotes: 0

Views: 678

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249656

You can use a mapped type to generate a union of all combinations of key/map possibilities. This union will enforce the constraint that the parameter to map will be the same type as T[K] and contextual typing will also work as expected:

type Test = {
  a: string;
  b: number;
}

type Foo<T> = { 
  [P in keyof T]: {
      key: P;
      map: (value: T[P]) => any;
  }
}[keyof T]

let o: Foo<Test> =  {
  key: "a", 
  map: v => v.toLocaleLowerCase() // v is string
};

let o2: Foo<Test> =  {
  key: "b", 
  map: v => v.toLocaleLowerCase() // v is number, so err
};

Play

Upvotes: 3

Related Questions