Home > OS >  Remap a type to flatten the first tier but keep the same structure of every tier after that
Remap a type to flatten the first tier but keep the same structure of every tier after that

Time:08-27

Given the below code:

// Given
interface Original {
  a: {
    aa: boolean
    ab: boolean
    ac: { cat: 'cat' }
  }
  b: {
    ba: boolean
    bb: boolean
    bc: { dog: 'dog' }
  }
}

// I want to remap to this
interface Remapped {
  aa: boolean
  ab: boolean
  ac: { cat: 'cat' }
  ba: boolean
  bb: boolean
  bc: { dog: 'dog' }
}

So basically I need to remove the first tier and merge the values of the first tier keys, but not any tears after that.

I've looked at other StackOverflow answers regarding flattening interfaces, but can only find examples where it flattens every property, but can't find examples where it keeps the same structure after the second tier.

Thank you in advance.

CodePudding user response:

You need to obtain a union of all values (type Values) and then merge it (type UnionToIntersection):

// Given
interface Original {
    a: {
        aa: boolean
        ab: boolean
        ac: { cat: 'cat' }
    }
    b: {
        ba: boolean
        bb: boolean
        bc: { dog: 'dog' }
    }
}

type Values<T> = T[keyof T]

// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
    k: infer I
) => void
    ? I
    : never;

type Result = UnionToIntersection<Values<Original>>

Playground

  • Related