What is a Branded Type?
Branded types (also known as "Nominal" or "Opaque" types) let us specify logic on the type level.
We'll start our exploration by looking at a password.
Normally a password
would just be a string
.
But by calling a special Brand type helper, we can turn this password
from a regular string
i
Transcript
0:00 In this section, we're going to be learning about branded types or nominal types. These types are really interesting, because they let you specify logic on the type level.
0:10 Here, we have a password here, and this password is just a string, but we can call this special brand thing over here. What that's going to do is it's going to turn this password from just a regular string into a password, so I can say as Password.
0:29 Now, inside this passwordSlot, this variable is expecting to be assigned as a password essentially. You shouldn't be able to assign it just like a regular string. If I delete some code here, I shouldn't be able to go, OK, pass it just a random password. It needs to be something that has been branded as a password.
0:49 Whereas if I do this and say as Password over here, then suddenly, this passes. To loo at this, this complicated piece of code, I've gone into helpers/Brand.ts here. We have a export type Brand, which takes in a T and TBrand, and it returns T and an object containing that brand assigned to a unique symbol.
1:16 This object here can never be satisfied at the runtime, because this declare const brand, it only exists at the type level. Declare const puts something into global scope that's a type that you can fulfill. You can say brand = something, something, something, but you're never going to be able to fulfill it, and it's a constant anyway.
1:38 This syntax lets you declare a globally unique symbol that you can then use in your brands that can never be satisfied. What this means is that when we brand something as something on the type level, it means that it has to be passed to a slot with that same brand.
1:55 For instance, we could have a, let's say, getPassword, for instance, or const verifyPassword, and what we're going to do then is take in a password here, which is going to be of type Password, and now verifyPassword, you can't just pass it one of these. It has to be...Of course, we start TS server. Let's see. Yeah, finally, you catch up.
2:16 Then you have to mark it as Password, or you'll see various tips in this section on how you can create these branded types of regular types.
2:28 That's the idea of branded types. You can do this, by the way, to anything. You can say, OK, I want to create a branded object. You can say type UserObject = Brand, and then we can pass in id string, name string, for instance, and then we have to give a name to, so we have to say User.
2:48 Then that User object, so const user, let's say, we can say this has to be a UserObject and we have to pass an ID and a name, and it has to be branded as a UserObject. There we go.
3:07 That's the idea behind brands. We'll see their various applications throughout this section, and how they can make your logic a lot safer. They let you do some really interesting stuff that just isn't possible with regular TypeScript.