TypeScript gives us as powerful feature called mapped types, which allows us to iterate (map) over different types or a union of different types and merge them into a new type.

Examples

interface Position {
  positionName: string;
};

interface Department {
  departmentName: string;
};

type PositionAndDepartment = {
  [P in keyof Position]: Position[P];  
} & {[D in keyof Department]: Department[D] | null};

But what if we want to map non-string types. How would we go about this? If we simply loop over the type similar to what we did above, we will get an error. In this case we need to use the as keyword.

type Item = 
| {
    type: "cereal";
    name:"Corn Flakes";
}
| {
    type: "price&inStock"
    price: 7.99;
    inStock: false;
}

type ItemMap = {
    [I in Item as I["type"]]: (item: I) => void;
};

Output:

type ItemMap = {
    cereal: (item: {
        type: "cereal";
        name: "Corn Flakes";
    }) => void;
    "price&inStock": (item: {
        type: "price&inStock";
        price: 7.99;
        inStock: false;
    }) => void;
}