In this blog post, we will take a look at how to use the new proposal const in Typescript to get literal types for objects but now inside functions. We will also discuss how to use generics to create more dynamic and powerful types for our objects, and how the upcoming Typescript 5.0 release will make this even easier to do.
First, let’s take a look at how we can use as const to get literal types for our objects. When we create an object like this:
If you create an object like this:
const typesLiteral = {
paul: 'McCartney',
john: 'Lennon',
}
you get this types back:
const typesLiteral: {
paul: string;
john: string;
}
but if you want the real value you can use as const
const typesLiteral = {
paul: 'McCartney',
john: 'Lennon',
} as const
and this will return the following type:
const typesLiteral: {
readonly paul: "McCartney";
readonly john: "Lennon";
}
but sometimes you need to send this object into a function and get the return with the literal type using generics:
const parseNames = <T>(names:<T>) => {
return names
}
const result = parseNames({
paul: 'McCartney',
john: 'Lennon',
})
but this will return the type like this:
paul: string;
john: string;
it is possible using the ts-toolbelt library but the docs are confusing
const parseNames = <T>(names:F.Narrow<T>) => {
return names
}
But with typescript 5.0
at github.com/microsoft/TypeScript/pull/51865
will be possible to implement like this:
// note that doesn't work with arrow functions
function parseNames <const T>(names:T) {
return names
}
and this makes the returned object more dynamic, powerful and flexible to work inside the functions improving the autocomplete.
so the in this example:
function parseNames<const T extends {name: string, yearOfBirth: number}>(names: T[]) {
const getName = (name: T['name'])=> names.find(n => n.name && n.name === name)?.yearOfBirth
return getName
}
const getData = parseNames([
{
name: 'Paul',
yearOfBirth: 1942,
},
{
name: 'Lennon',
yearOfBirth: 1940,
}
]);
const year = getData("Paul");
we will get a function with autocomplete like this
const getData: (name: "Paul" | "Lennon") => number
This is a huge improvement to make the data more dynamic and way more reliable.
Typescript 5.0 final release is expected to March 14th 🚀