Creating Validation Boundaries with Branded Types
Now let's go a little deeper.
Here are several functions that are used to handle a currency conversion request.
The getConversionRateFromAPI
function takes in an amount
and the from
and to
currency:
const getConversionRateFromApi = async ( amount: number, from: string,
Transcript
0:00 Let's go deeper. This is quite a lot of logic that we're expressing here and we basically want to make sure that it's performing as it is on the type level. This idea here is we're handling a conversion request. This is like a fintech app where we're converting from one currency to another.
0:17 What we're doing first is we're saying, await getConversionRateFromApi. We're taking in the amount, the from currency and the to currency here. We're basically getting that converted amount back.
0:30 Then we're passing that converted amount to a ensureUserCanConvert, where we pass in the user and then we pass in the converted amount, and we get back an authorized user. Then we pass that authorized user into the performConversion function, which actually does all the converting.
0:47 The way I've done this is, I've structured this inside a test where this is one example in the implementation which is all sort of passing, and it should pass. What I want to do is actually, I've given you a couple of other example implementations where they've skipped a step.
1:02 In this one, they've skipped the getConversionRateFromApi. They've not actually converted the amount first and they're using just the raw number, which would be bad, would be real bad. Then, in this one, should error if you do not authorize the user first. Even worse.
1:19 Unauthorized users can just perform conversions. Terrible. You want to be able to do this on the type level. Of course, you would probably have a unit test to cover this, but having it on the type level is really, really nice too.
1:32 I've given you no brands in this exercise, but you do have access to the brand type helper. You're going to have to try to make this work by adding in the correct errors here by branding certain functions with what they're expected to receive.
1:47 This is a really cool logic puzzle and it shows off the power of branded types. Good luck.