Search code examples
typescripttypestype-conversiontypescript-typingsunion-types

Transform type keys to union with optional parameters


Is there a way type to transform the Screens type into ScreensNew type?

What I want to do is:

  • Transform all first level keys into strings (like keyof)
  • Keep the other parameters as is (strip undefined)
  • Make a union type of each property afterwards
type Screens = {
  First: undefined;
  Second: {
    name: string;
  }
}
type ScreensNew =
  | "First"
  | "Second": { name: string; }
}

Solution

  • The type in your post is not a valid TS type. We can create a discriminated union of the form type ScreensNew = | { type: "First" } | { type: "Second", name: string; }:

    type Screens = {
      First: undefined;
      Second: {
        name: string;
      }
    }
    
    type CreateDiscriminatedProps<T> = T extends undefined ? {} : T
    type CreateDiscriminated<T> = {
      [P in keyof T]: { type: P } & CreateDiscriminatedProps<T[P]>
    }
    
    type ScreensNew = CreateDiscriminated<Screens>
    
    //Same as
    // type ScreensNew = {
    //     First: {
    //         type: "First";
    //     };
    //     Second: {
    //         type: "Second";
    //     } & {
    //         name: string;
    //     };
    // }
    

    Playground Link