Structural vs Nominal Typing


Structural Typing


One other thing to note is that different ways of describing structured types, such as classes, interfaces, and literal object types, are all structurally equivalent as well. All three of these types are equivalent in TypeScript:


Nominal Typing


Other programming languages, like Java and C# use a nominal type system. The word "nominal" refers to the name of the thing, which means if I were to create two classes with an identical structure, but different names, those two classes would be considered different.

Like we saw with the **Apple** and **Banana** classes, we can emulate nominal typing by adding a unique property to our types with a string literal type. This practice is called "branding", or "tagging", and is what allowed us to differentiate between the two types in the type system.

When using a branded type, you want to make sure you assign your variables with the correct type; otherwise TypeScript will infer the type based on what value you put in your variable.

This makes it possible to discriminate between types that may have the same structure, but different purposes.

We can also create what are called "branded primitives". This allows us to create primitive values which are only assignable to variables and parameters that match a specific type signature.

We first create our branded primitive type. In this case, I'll make a number that represents money from different countries.

Then, we can assign it to variables. If we just try assigning numbers to variables annotated with our branded types, TypeScript will give a warning.

Instead, we have to use an assertion signature to convert our number type into the branded type. Then, we won't be able to assign **USD** numbers to **EUR** variables without converting the type (and value if necessary) first.

Now, not only are our objects type safe, but our units are type safe too!

Copyright 2023 © Borja Leiva

Made within London