I got a message from my friend Tom on Twitter the other day:
Hey @mattpocockuk this is really bugging me!
I'm sure there was a feature that let me do
fn('hello')
and it'd be equivalent to
fn('hello' as const)
Can't find any docs about it tho, have I made this feature up?
Turns out he hadn't made it up.
TypeScript 5.0 introduced a brand-new piece of syntax to the language: const
type parameters.
const myFunc = <const T>(input: T) => {
return input;
};
To understand why it's useful, let's first take a look at a function that doesn't use a const
type parameter:
const myFunc = <T>(input: T) => {
return input
}
Let's say you call myFunc
using an object:
const result = myFunc({foo: 'bar'})
The type of result
will be { foo: string }
. This is exactly the same as if you'd declared your object as a variable:
const myObj = {foo: 'bar'} // { foo: string }
If you hover over myObj
in VS Code, you'll see that the type is the same as above - { foo: string }
.
But what if we don't want to infer a string
, but instead the literal bar
?
On the variable, we can use as const
to do this:
const myObj = {foo: 'bar'} as const // { readonly foo: "bar" }
But how do we handle it on the function? Enter the const
type parameter:
const myFunc = <const T>(input: T) => {
return input;
};
const result = myFunc({ foo: "bar" }); // { readonly foo: "bar" }
This is a really useful way of preserving the literal types of objects passed to your functions.
How are you planning on using const type parameters? Let me know on my Discord Server.