Mutability 12 exercises
solution

Understanding Object Properties and Assignability in TypeScript

Like before, we have an errors that the buttonAttributes type string is not assignable to type "button" | "submit" | "reset".

We get this error because even though the variable was declared with const, JavaScript allows us to modify object properties. This means that TypeScript also treats o

Loading solution

Transcript

00:00 Okay, let's figure this out. Button attributes then, why is this not assignable to the other one? Well, type string is not assignable to type button, submit, or reset. Huh, we've got a very similar problem. Even though we've declared our object with const, JavaScript actually lets you modify

00:18 object properties in here. So we can't modify the actual thing itself, so we can't say button attributes is something different because you can't reassign to it, it's a constant. But object properties are fair game, thanks JavaScript. But that is JavaScript's behavior, so TypeScript is copying it. You can kind of make this a little bit easier

00:38 and make it work. The first way you can do it is actually just inline this. So you can just say, okay, modify button, passing in the type of button. TypeScript understands that in this setup, really, you can't modify this object literal before it gets passed in there, it's literally in the parentheses.

00:55 And so it will let you do it, that's perfectly fine. But the other way you might need to be able to do it is just by adding a type here. So with a little extra type hint, you tell TypeScript, okay, this is button attributes, it does exactly the same thing, it checks if it's button reset or submit, and you're good to go.

01:12 So this is, I think, the sort of best way to get around this, either inlining it or just giving it the type straight up. The same thing is true with arrays. So with arrays, just behave like objects, we're now getting an array of type string here, or objects of type string. And it means that we can go into here and we can say button attributes,

01:30 zero dot, or it might need to be this, dot type, oh, buttons to change, that's it. Buttons to change, first one, grab the type and set it to something different, right? And we're getting an array here because it's, I think it's an optional chain. There's lots of fun stuff going on here,

01:49 but basically we can do this. And because we can do this, TypeScript is scared of it, and so it won't infer properly. So the best way to get around this is to say button attributes and give it basically an array property on the end. So this means now that, and again, it would pick it up really nicely

02:08 if we just inlined it. And so often what I find myself doing is not really declaring that many variables outside of functions if all I'm doing is passing them directly in. It doesn't make a huge amount of sense to do that when you can just pass them in literally. So this is something that you might wanna change about

02:26 the way that you write your TypeScript. There are a couple of extra annotations that we'll see in this chapter that can help us out further down the line, but I want to give you a proper sense of how object properties infer so that you can kind of change the way maybe you declare your variables and mostly you're gonna want to inline them.