How to Get Stricter Types in TypeScript with Const Generics
Sometimes, TypeScript doesn’t give you the exact type of data you expect. For example, when you have a list of numbers, you might want TypeScript to know it’s exactly 1, 2, or 3. But often, it just says it’s a ‘number’.
This can cause problems in larger projects. Luckily, there’s a way to fix this using a feature called ‘const generics’. This article shows you how to use them to get more precise types without extra work.
What You Will Learn
You will learn how to use const generics in TypeScript. This technique helps TypeScript understand your data more precisely.
You’ll see how it works with a simple example and understand why it’s useful for your coding projects. We’ll explain how to get specific types instead of general ones.
Prerequisites
- Basic understanding of TypeScript functions and types.
- Familiarity with generic types in TypeScript.
Step 1: Understand the Problem with Basic Generics
Let’s start with a simple function. Imagine you have a function that takes a list of items and gives you back the first item. If you give it the list [1, 2, 3], you’d expect the result to be exactly 1, 2, or 3.
But if you check the type, TypeScript might just say it’s a ‘number’. This is too general and can lead to errors later on.
This happens because TypeScript, by default, treats function inputs as potentially changeable. It doesn’t assume the list will stay exactly [1, 2, 3] forever. This is like saying you have ‘fruit’ instead of ‘an apple’, when you really have an apple.
Step 2: Use ‘as const’ for Stricter Types
One way to get a more specific type is to tell TypeScript that your list is a constant. You do this by adding ‘as const’ after the list when you pass it to the function. So, instead of just `[1, 2, 3]`, you would write `[1, 2, 3] as const`.
When you use ‘as const’, you’re telling TypeScript, ‘This list will not change, and its values are exactly these.’ Now, if you check the type of the first item, TypeScript will correctly show it as the specific type, like ‘1 | 2 | 3’ (meaning it’s 1, or 2, or 3).
Expert Note: ‘as const’ makes the type read-only and as specific as possible. This is great for ensuring your data doesn’t accidentally change and for getting precise type information.
Step 3: Introduce Const Generics to Avoid ‘as const’
Having to add ‘as const’ every time can be a bit annoying. What if you want the function to automatically be stricter without you having to add ‘as const’ every time you call it?
This is where ‘const generics’ come in. You can add the word ‘const’ right before the name of a generic type. For example, if your function uses a generic type `T`, you can change it to `const T`.
Step 4: How Const Generics Work
When you use ‘const’ before a generic type parameter, like `function myFunction(value: T)`, it tells TypeScript to treat the value passed to that generic as if ‘as const’ was used on it. It automatically applies that stricter, read-only typing.
So, if you pass the list `[1, 2, 3]` to a function using a const generic, TypeScript will treat it as a constant array with specific values. The type you get back will be precise, like ‘1 | 2 | 3’, without you needing to write ‘as const’ yourself.
Think of it like this: Using ‘as const’ is like putting a label on your box saying ‘Fragile – Do Not Open’. Using a const generic is like the person receiving the box automatically knowing it’s fragile and handling it with extra care, even without the label.
Step 5: Benefits of Using Const Generics
While using ‘as const’ works for single instances, const generics are more powerful for reusable code. They ensure that functions always receive data with the strictest possible type, making your code safer and more predictable.
This feature is especially useful in complex TypeScript projects where managing types precisely can prevent many bugs. It helps ensure that data is treated as intended, preventing accidental modifications and improving type checking accuracy.
Start using const generics today to make your TypeScript code more robust and easier to manage.
Source: I Can’t Believe This TS Feature Has No Documentation (YouTube)