Search code examples
typescriptmapped-types

Is it possible to change property shape with mapped types?


I have type like this

type Foo = {
   x : Bar<A>
   y : Bar<B>
}

or

type Foo = {
  x: {item:A}
  y: {item:B}
}

And I want to express this type

{
  x: A
  y: B
}

In pseudocode it could look like this

type Flatten<T> = {
    [P in keyof T where T[P] extends {item: X}]: X;
}

Is it possible to do something like this?


Solution

  • It's possible with the second variant of Foo, where a type of each member has itself a member with the same name (item), so you can use indexed access type operator ['item'] inside mapped type:

    type A = string;
    type B = number;
    
    type Foo = {
      x: {item:A}
      y: {item:B}
    }
    
    type M<F extends {[n in string]: { item: {} }}> = {
        [n in keyof F]: F[n]['item']
    }
    
    type U = M<Foo>; // type U = { x: string; y: number; }