Typescript Utility Types: Required<T>
Introduction
The Typescript Required<T>
utility type provides a wonderful means converting optional properties to be mandatory instead.
Let’s dive into an example to better understand the problem it solves!
Problem Example
interface Person {
name: string
email?: string
}
We define an interface called Person
with two properties. A mandatory string name
property and an optional string email
property.
Let’s define a function that accepts an instance of Person
as an argument.
const printPerson = (person: Person) => {
console.log(`Name: ${person.name}`)
console.log(`Email: ${person.email}`)
}
Brilliant!
Let’s instantiate a Person
instance and pass it to the function printPerson
.
const person: Person = {
name: "Jamie"
}
printPerson(person)
We create an instance of Person
with an undefined email
value. This is perfectly valid since the Person
interface is defined with an optional email
property.
As you can imagine, this can lead to some unexpected outputs since our printPerson
function assumes the presence of an email value (instead of undefined).
Well how can we solve this problem?
One possible solution would be adding a guard clause to the printPerson
function that checks for a valid email
value.
const printPerson = (person: Person) => {
if (!person.email) {
throw new Error("You must provide an email")
}
console.log(`Name: ${person.name}`)
console.log(`Email: ${person.email}`)
}
This seems tedious!
Another, possible solution would be to define another interface. One that looks exactly like Person
except for a mandatory email
property. We could then change the printPerson
function signature to instead accept an instance of the new interface.
interface PersonRequired {
name: string
email: string
}
This certainly looks like a better solution. However, it seems even more tedious.
I wonder if we could achieve this without the need to define a new, almost identical interface…?
Enter the Required<T>
utility type to save the day!
Solution
The Required<T>
utility type converts all optional properties of a type to mandatory!
const printPerson = (person: Required<Person>) {
console.log(`Name: ${person.name}`)
console.log(`Email: ${person.email}`)
}
And there you have it!
By simply defining the type of the Person
argument in the printPerson
function signature as Required<Person>
we have provided a means to mark all the optional properties of that Person
instance as mandatory.
This certainly looks a lot cleaner while at the same time reducing the amount of code we’d have to write to ensure type-safety.
We also get the added benefit of compile time error checking supporting our efforts to write more robust and less error-prone code.
Conclusion
The Required<T>
utility type provides a neat way for us to write type-safe code, with compile time error checking without needing to write guard clauses or define almost identical interfaces.
Subscribe to my newsletter
Read articles from Wendel Fabian Chinsamy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Wendel Fabian Chinsamy
Wendel Fabian Chinsamy
Hello! I'm Wendel. A software engineer from Johannesburg, South Africa. I'm very passionate about learning and teaching and I'm using this platform as an opportunity to document my rise through the world of JavaScript. Join me!