Let's say we have the following string union type to define all the possible values of a status:
type Status = "Completed" | "Pending" | "Canceled";
We also have another string union type to define all the possible colors of a badge component:
type BadgeColor = "green" | "yellow" | "red";
We have the following object to map statuses with badge colors:
const statusColors = {
Completed: "green",
Pending: "yellow",
Canceled: "red",
};
We'd like to type this object to make sure we will never forget to update it, in case we add or remove a status value. TypeScript should throw an error to let us know.
How can we achieve that?
We can annotate the object as follows combining an index signature with the
JavaScript in
operator:
const statusColors: { [key in Status]: BadgeColor } = {
Completed: "green",
Pending: "yellow",
Canceled: "red",
};
Now, if we add a new status Unknown
to the Status
union type, TypeScript
complains:
Property 'Unknown' is missing in type '{ Completed: "green"; Pending: "yellow"; Canceled: "red"; }' but required in type '{ Completed: BadgeColor; Pending: BadgeColor; Canceled: BadgeColor; Unknown: BadgeColor; }'.
If we remove the status Pending
, TypeScript will also complain:
Object literal may only specify known properties, and 'Pending' does not exist in type '{ Completed: BadgeColor; Canceled: BadgeColor; }'.
If we try to assign a non-existing BadgeColor
, TypeScript will also complain:
Type '"blue"' is not assignable to type 'BadgeColor'.