Type tagging, also known as branding, is a common practice in advanced TypeScript setups. The main purpose of this approach is to make certain primitive types more predictable. Using branded types leads to a better traceability of data in the project and encourages developers to be more aware when working with critical, primitive data.
Quick Start
Let's have a look at this example below:
typeUUID=stringtypeUser={id:UUID}
We have created a type alias UUID that is used on the type User. Right now, any string value is a valid UUID:
constuser:User={id:"some-uuid"}
This is very implicit, not traceable, and is not very safe since you pay less attention to what is passed around, since everything is just a string.
What if we could make this more explicit?
import{Tag}from"@corets/tag"typeUUID=Tag<string,"uuid">typeUser={id:UUID}// this will not work since string is not assignable to UUIDconstuser1:User={id:"some-uuid"}// exlicitly cast it to UUIDconstuser2:User={id:"some-uuid"asUUID}
Now we are using a branded string instead of plain string. You can not assign a plain string to a UUID anymore, if you do so, you have to cast it explicitly. Now you also have full traceability on where UUIDs are used in the project.
Tag<type, alias>
Creates a branded type for any primitive value:
You get full traceability of where branded types are used in your project, since you always have to cast a primitive value to that specific type.
import { Tag } from "@corets/tag"
const Email = Tag<string, "email">
// this will work
const email2: Email = "[email protected]" as Email
// this will not work
const email1: Email = "[email protected]"