A branded type is a type that contains an additional property to give it a unique identity.
type Uuid = string & {
_type: "@safelytyped/uuid";
}
type CombUid = string & {
_type: "@safelytyped/combuid";
}
In this example, we've added an interface
to a string
to create two different types: Uuid
and CombUid
.
The interface
contains the property _type
, whose type is @safelytyped/uuid
or @safelytyped/combuid
. (They looks like values, but they're not.)
These _type
properties are part of the structure of Uuid
and CombUid
. They make each structure unique. The compiler will now treat Uuid
and CombUid
as different types. Without the _type
property, the compiler would treat them as the same type. This is called structural typing.
Because interfaces only exist at compile-time, our example Uuid
and CombUid
types both turn into string
once the code is compiled. The interface disappears, and has zero runtime overhead.
You can add these interfaces to any Typescript type - including classes! - to emulate nominal typing.
See also flavoured types for an alternative.