Search code examples
typescripttypescript-typingsunion-types

A way to distribute string union to another Type


I currently have some Typescript code that looks like this :

type UserRole = "admin" | "partner" | "associate";

type User<Role extends UserRole> = {
    // ...
    role: Role;
   //  ...
}

type Users = User<"admin"> | User<"partner"> | User<"associate">

I use the Role type parameter on the User type to have dynamic typing over other properties of User in a switch(user.role) block.

Is there a way here to not manually write type Users = User<"admin"> | User<"partner"> | User<"associate">, but to "loop" over the UserRole string union instead, in order to distribute it to the User type ?

In other words, how could I write a type that would "distribute" the string union on my User type this way :

type Distribute<T, S> = // ?????
type Users = Distribute<User, UserRole>; // = User<"admin"> | User<"partner"> | User<"associate">

Thanks in advance,

Stay safe


Solution

  • You can use the distributive property of conditional types. Since we don't actually want to use the conditional part of conditional type, we will use an always true condition such as T extends T

    type UserRole = "admin" | "partner" | "associate";
    
    type User<Role extends UserRole> = {
        // ...
        role: Role;
       //  ...
    }
    type DistributeUsers<T  extends UserRole> = T extends T ? User<T> : never
    type Users = DistributeUsers<UserRole>
    

    Playground Link