Mutability 12 exercises

Deeply Apply Read-only Properties with as const

In TypeScript, using Object.freeze is a common method for creating immutable objects. However, there are some significant differences between Object.freeze and as const.

When applying Object.freeze to the buttonAttributes object, we can see that a read-only modifier is being inferred on t

Loading solution


00:00 Okay, so the difference between object.freeze and as const is kind of what we're looking at here. If we hover over button attributes, you'll see that there's a read-only modifier being applied to the object that's being inferred here.

00:13 But you'll see that cancel type is still inferred as string here, and not the literal of button. Oh, dear. So object.freeze, as it turns out, it only works on the top level. So if we were to add another type up here, let's say type blah, blah, blah,

00:32 then when we hover over button attributes, you can see that this is type blah, blah, blah, and then if we try to modify this, you see button attributes.type is this. We would get an error here. But as we can see, if we go one level down, if we go confirm.type, then there's no more error.

00:51 So the difference between object.freeze and as const is that object.freeze, first of all, runs at runtime, so it's more costly, and it doesn't go all the way down the object. It's not recursive. It only works on the very top level. So the way to fix this is instead of using object.freeze,

01:09 is to say as const, and of course, remove the extra type we added in there. So there we go. Button attributes now, if we hover over it, it's read-only all the way down, the whole tamale. So we've got read-only cancel, read-only type is button, and it's inferring those literals too. So in general, object.freeze, I think is not a great idea to use,

01:28 unless you really want to make sure it's frozen at runtime. As const has no runtime cost and does it recursively. Super nice.