I recently discovered the TypeScript satisfies
operator which solves a particular typing problem I’ve come across time and time again.
satisfies
OperatorIn a nutshell, it ensures that something conforms to a specific type while also giving that thing the most specific (inferred) type.
Let’s say we have an object where the keys are strings and the values are objects. And we know that in the future we might add another section like section3
.
Sometimes we might want a type that is the keys of our sections
object.
Cool, now we have type called SectionNames
that is very specifically one of two string literals (section1
or section2
).
But wait, we want the sections
object to conform to a specific shape. Specifically, we want two things:
- We want to be able to add additional sections to the object
- Each section should be an object that has the key
detail1
with astring
value
So we might do something like:
This allows us to add as many sections as we want (without having to also add the same section key to some overall Sections
interface) and each section must be an object with the specified key/value pairs.
There’s a problem though. Let’s look at what our SectionNames
type looks like now:
Now SectionNames
is just of type string
.
Because we typed sections
as Record<string, SectionDetails>
, TypeScript is no longer inferring the more specific type.
So the question is, how can we ensure that sections
conforms to the shape we want while also having our SectionNames
type be the exact keys and not just string
?
This is where the satisfies
operator comes in. Instead of specifying the type of sections
, we say it must satisfy some type: