Change Function Returns Based on Type
For this solution, we'll start with getting the tests to pass and then work on the types.
Inside of the
coerceAmount function we can check if
amount.amount exists, then return it. Otherwise, return
Now our tests will pass, but TypeScript gives us an error.
amount.amount tells us:
Property 'amount' does not exist on type number.
This is a TypeScript quirk where you can't access a property unless you know it's there.
Check Amount's Type
One way to fix the type error is updating our
if to check if the
typeof amount is an object. If so, return
amount.amount otherwise just return
This would also work by checking if
typeof amount is number, then return the amount. Otherwise, return
typeof operator to narrow down different branches of a union type is really powerful technique.
It's also really useful when interfacing with APIs that you didn't create.
For this one, I'm actually going to try and fixing it live so I can show you the problems that you might have run into. CoerceAmounts. Let's just try and get the test passing first. We can say if amount.amount, which represents our object, then we can return amount.amount, otherwise return amount. Are you sick of seeing the word amount yet?
Now our tests are passing, but our types are not passing. Because amounts here it's saying property amount does not exist on type number or amount number. This is a funny little quirk of TypeScript, which is you can't access a property unless you know it's there. It's going to be strict with you on that.
What that means that you should do is we need to write this in reverse. We need to check for the number here and then return the object in the second branch. You can do this with...Matter of fact, we can do it this way too. You can do this with typeof.
Now typeof, if typeof amount === "object", then what we can do is it then knows which branch of this union it's looking at. It's saying if typeof amount === "object", then we know that it's this one. Because if we ran typeof, and it was in this branch, then it would return number. Actually that means that you can hover over this and it will show you that amount.
Whereas down here, it's now typed as amount number. You can do this in reverse too, which is what I did for the solution. If typeof amount === "number", then return amount, There. This typeof operator, the idea that you can narrow TypeScript down and get it to understand two different branches of a union just with a typeof, is really powerful.
It's really powerful for interfacing with APIs that you didn't create as well.