Search code examples
typescripttypesunion-typesmapped-types

Typescript union types to keys on other union type


I've got a union type, say:

type BooleanOperator = "and" | "or";

I want to create another union type that is based on it:

type ConditionMap_Good = { and: string[] } | { or: string[] }

However, I've only been able to do this manually, written as above, which won't be feasible when the original union has many cases.

I know of mapped types, but what they generate doesn't match what I want:

type ConditionMap_Bad = {
    [K in BooleanOperator]: string[]
}

// type ConditionMap_Bad = {
//     and: string[];
//     or: string[];
// }

Is there a concept or construct in Typescript to help me define what I want?


Solution

  • As the linked answer says, you need to use distributive conditional types to "map" over the union and you will need to use a mapped type to get the string to be key of the object type.

    type ConditionMap = 
      BooleanOperator extends infer U extends string
        ? U extends U 
          ? { [K in U]: string[] }
          : never
        : never
    

    Here is also a reusable generic variant.

    type ToConditionMap<T extends string> = 
      T extends T
        ? { [K in T]: string[] }
        : never
    

    Playground