Prevent Type Widening of Array Literals with TypeScript's const Assertions

Marius Schulz
InstructorMarius Schulz

Share this video with your friends

Send Tweet
Published 2 years ago
Updated 2 years ago

A const assertion is a special type assertion that uses the const keyword instead of a specific type name. When using a const assertion on an array literal expression, the resulting type will be a readonly tuple type and no literal types within the expression will be widened.

Instructor: [0:00] We can also use const assertions with array literals. In this example, I've modeled our point to be a 2-tuple. However, TypeScript is inferring the type number array, which is not what we want here. We would want TypeScript to treat this as a tuple of two numbers. Ideally, we would even want this to be a read-only tuple of two numbers.

[0:23] As you can see, our type annotation is getting quite verbose already. Instead of adding this type annotation, we can use a const assertion again. With this const assertion in place, TypeScript will infer a read-only tuple type. Once again, it's going to infer the numeric literal type rather than widening that to the type number.

[0:46] If we now try to modify one of the tuple elements, TypeScript will give us a TypeError. That's because we have a read-only tuple, so we cannot just change one of its elements. If you think back to the previous lesson about read-only array and tuple types, const assertions would have been useful here.

[1:06] Remember that we added a tuple type annotation here so that we would get a tuple type and not an array type. Instead of adding this type annotation, we could have used a const assertion instead. Once we add the const assertion, TypeScript will infer a read-only tuple type with two elements.

[1:24] Once more, TypeScript is going to infer the most specific types possible. Instead of inferring type number and type string, we now have the numeric literal type 1 and the string literal type "One."

[1:40] Const assertions are particularly helpful if you have slightly more complex literal expressions. In this case, I have declared an array of tuples, but what TypeScript sees is an array of arrays that contain either strings or numbers. That type is not as specific as we would like.

[1:59] What we can do is add a const assertion. Now, TypeScript is going to infer a much more specific type, granted the type is quite verbose, but it is precisely describing our digit names.