Designing Your Types 11 exercises

Combine the `as` Keyword with Template Literal Types

Our goal is to create a new mapped type, AttributeGetters, that changes each key in Attributes into a new key that begins with "get" and capitalizes the original key. For example, firstName would become getFirstName.

Before we get to the solution, let's look at an incorrect approach.


Loading solution


00:00 So the way that this first might come to mind is you might think, okay, I'm going to transform key of attributes before it even gets to the map type. So you might say like this, okay, I can use a template literal type. I can say, new attribute keys. And I can say, let's use a template literal type.

00:18 Let's pass it to, let's pass key of attributes inside here. And then inside there, I'm going to say, okay, key of attributes so far, brilliant. I'm going to say get, add get to the start of it. And so you end up with get first name, get last name and get age. But then you notice that it's not capitalized. It's not quite right.

00:36 So I can use the capitalize type helper, which yes, is a global in TypeScript to capitalize it. So you end up with get first name, get last name and get age. And this is great. And so now I can say, okay, in key of new attribute keys, but what ends up happening is not great.

00:55 If we look at attribute getters, oh dear, something. Oh no, it's not key of attribute keys. It's just new attribute keys. Great. So if I look at this, like I've got my keys working perfectly now, but it turns out that attributes k, k can't be used to index type attributes because they don't exist on the attributes themselves.

01:14 So we need access to like the original key inside here. So k needs to stay the same. So let's just say key of attributes. And inside there, we somehow need to do some remapping inside there to remap k to the new value. Turns out you can do this with an as keyword after key of attributes.

01:34 So you say k in key of attributes as, and now we can say get, and we're going to copy the same logic, capitalize k. Look at that. So now inside there, we get get first name, which returns, basically, we still get access to the original key inside here.

01:53 So we could still, if I just grab this out, then we get attributes k and k. And so we've still got access to first name, last name and age. So we can index into the original attributes interface. Isn't that just crazy what you could do here? There's so much potential here for like,

02:11 there's functions out there that camelcase keys using template literal types. This is such a powerful ability. And just being able to say, okay, within this closure, I have access to the original key and the new key is just so, so cool.