Take a look at this code:
// path: className pair
const obj: Record<string, string> = {
'/about': 'bg-orange',
'/contact': 'bg-purple',
'/services': 'bg-yellow'
}
function getClassName(key: string) {
return obj[key]
}
We have obj
which has paths as the keys, and background classes as the values. Then we have a key
parameter which we have typed to string
. While this is fine, you can improve this by using a literal type instead. Here’s why:
// path: className pair
const obj: Record<string, string> = {
'/about': 'bg-orange',
'/contact': 'bg-purple',
'/services': 'bg-yellow'
}
// in some other file
function getClassName(key: string) {
return obj[key]
}
getClassName('/products') // undefined
In the case that you access a key that doesn’t exist, you would get undefined
. /products
is a string, so TypeScript doesn’t complain. TypeScript will only complain when you use a key that isn’t a string:
const obj: Record<string, string> = {
'/about': 'bg-orange',
'/contact': 'bg-purple',
'/services': 'bg-yellow'
}
// in some other file
function getClassName(key: string) {
return obj[key]
}
getClassName(/**/400/**/)
Argument of type 'number' is not assignable to parameter of type 'string' Instead of using key: string
, which allows for different forms of strings, you can narrow the accepted strings with literal types:
// path: className pair
const obj: Record<string, string> = {
'/about': 'bg-orange',
'/contact': 'bg-purple',
'/services': 'bg-yellow'
}
type Path = '/about' | '/contact' | '/services'
function getClassName(key: Path) {
return obj[key]
}
getClassName(/**/'/products'/**/)
Argument of type '"/products"' is not assignable to parameter of type 'Path' Here, we have a union of a literal type for Path
which means "/about"
or "/contact"
or "/services"
. Now when you provide "/products"
as the key, even though it is still a string like the others, we get an error.
But everything works fine when you pass the expected key:
// path: className pair
const obj: Record<string, string> = {
'/about': 'bg-orange',
'/contact': 'bg-purple',
'/services': 'bg-yellow'
}
type Path = '/about' | '/contact' | '/services'
function getClassName(key: Path) {
return obj[key]
}
getClassName('/about')
Although this works fine, you can improve it even further. Check out my keyof typeof magic tip.