Make an optional property Required in TypeScript

avatar

Borislav Hadzhiev

Last updated: Mar 19, 2022

banner

Photo from Unsplash

Make an Optional property Required in TypeScript #

To make an optional property required, create a utility type that uses a mapping modifier to remove the optionality for the specific property. The new type will have the specified property marked as required.

index.ts
interface Employee { id?: number; name: string; salary?: number; } type WithRequiredProperty<Type, Key extends keyof Type> = Type & { [Property in Key]-?: Type[Property]; }; // 👇️ Make salary required const emp1: WithRequiredProperty<Employee, 'salary'> = { name: 'James', salary: 100, }; // --------------------------------------------------------- // 👇️ Alternatively, extend the interface or type alias // and override properties interface EmployeeWithSalary extends Employee { salary: number; // 👈️ is now required id: number; // 👈️ is now required } const emp2: EmployeeWithSalary = { id: 1, name: 'Alice', salary: 200, };

The first example shows how to create a utility type that takes a type and a property name and makes the property required.

You can use the utility type to make more than one property required, by separating their names with a pipe.

index.ts
interface Employee { id?: number; name: string; salary?: number; } type WithRequiredProperty<Type, Key extends keyof Type> = Type & { [Property in Key]-?: Type[Property]; }; // 👇️ Make salary and id required const emp1: WithRequiredProperty<Employee, 'salary' | 'id'> = { id: 0, name: 'James', salary: 100, };

The -?: syntax is called a mapping modifier is used to affect optionality.

It is used in the built-in Required utility type, which looks like this:

index.ts
/** * Make all properties in T required */ type Required<T> = { [P in keyof T]-?: T[P]; };

In our case, we only make a single property required.

index.ts
interface Employee { id?: number; name: string; salary?: number; } type WithRequiredProperty<Type, Key extends keyof Type> = Type & { [Property in Key]-?: Type[Property]; }; const emp1: WithRequiredProperty<Employee, 'salary'> = { name: 'James', salary: 100, };

An alternative and perhaps easier to read solution is to extend the type alias or interface and override the properties you want to set to required.

To make an optional property required, extend the interface or type alias creating a new interface where you override the specific optional properties and setting them to required.

index.ts
interface Employee { id?: number; name: string; salary?: number; } interface EmployeeWithSalary extends Employee { salary: number; // 👈️ is now required id: number; // 👈️ is now required } const emp2: EmployeeWithSalary = { id: 1, name: 'Alice', salary: 200, };

The EmployeeWithSalary interface extends Employee and overrides the salary and id properties, setting them to required.

If any of the required properties are omitted, we would get a type checking error.

index.ts
interface Employee { id?: number; name: string; salary?: number; } interface EmployeeWithSalary extends Employee { salary: number; // 👈️ is now required id: number; // 👈️ is now required } // ⛔️ Error: Property 'id' is missing in type // '{ name: string; salary: number; }' but // required in type 'EmployeeWithSalary'.ts(2741) const emp2: EmployeeWithSalary = { name: 'Alice', salary: 200, };
I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.