TypeScript is a popular programming language that offers static type-checking and enhances the developer experience. One of the key features of TypeScript 5.0, the newest TypeScript version, is its ability to infer types. However, when inferring the type of an object, TypeScript often chooses a type that’s too general. This can lead to issues down the line, especially if mutation is required.
In this article, we’ll explore how TypeScript 5.0 has improved type inference by introducing const type parameters. We’ll look at how const type parameters work, when to use them, and some examples of how to use them effectively.
What are Const Type Parameters?
When TypeScript infers the type of an object, it typically chooses a type that’s meant to be general. This is often done to enable mutation down the line. However, depending on what the function does and how it’s intended to be used, a more-specific type may be desired. Up until now, API authors have typically had to recommend adding “as const” in certain places to achieve the desired inference.
TypeScript 5.0 introduces const type parameters, which allow you to add a const modifier to a type parameter declaration. This causes const-like inference to be the default. In other words, TypeScript will infer a readonly type by default, without the need to add “as const” in certain places.
How to Use Const Type Parameters
To use const type parameters, you simply add the const modifier to the type parameter declaration. Here’s an example:
type HasNames = { names: readonly string[] };
function getNamesExactly<const T extends HasNames>(arg: T): T["names"] {
return arg.names;
}
const names = getNamesExactly({ names: ["Alice", "Bob", "Eve"] });
In this example, the const modifier is added to the type parameter declaration. This causes the inferred type of “names” to be readonly [“Alice”, “Bob”, “Eve”], which is the type we wanted. We didn’t need to write “as const” in this case.
When to Use Const Type Parameters
Const type parameters should be used when you want to ensure that a more-specific type is inferred, without the need to add “as const” in certain places. However, it’s important to keep in mind that the const modifier only affects inference of object, array, and primitive expressions that were written within the call.
For example, in the following code:
declare function fnGood<const T extends readonly string[]>(args: T): void;
const arr = ["a", "b" ,"c"];
fnGood(arr);
The inferred type of “arr” is still string[], since the const modifier has no effect here. Therefore, you should only use const type parameters when you need to ensure that a more-specific type is inferred within the call itself.
TypeScript 5.0 introduces const type parameters, which allow you to add a const modifier to a type parameter declaration. This causes const-like inference to be the default, without the need to add “as const” in certain places. Const type parameters should be used when you want to ensure that a more-specific type is inferred within the call itself. By using const type parameters, you can improve the accuracy and reliability of your code, and avoid common issues down the line.