Make an optional property Required in TypeScript

avatar
Borislav Hadzhiev

Last updated: Feb 28, 2024
3 min

banner

# Table of Contents

  1. Make an Optional property Required in TypeScript
  2. Make all properties required in TypeScript

# 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 specified 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: 'Bobby Hadz', salary: 100, };

make optional property required in typescript

The code for this article is available on GitHub

We created 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: 'Bobby Hadz', 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: 'Bobby Hadz', 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.

# Extend the type alias or interface

Alternatively, you can extend the interface or type alias, creating a new interface where you set the optional properties 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: 'Bobby Hadz', salary: 200, };

extend type alias or interface

The code for this article is available on GitHub

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 will 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: 'Bobby Hadz', salary: 200, };

# Make all properties required in TypeScript

Use the Required utility type to make all of the properties in a type required.

index.ts
interface Employee { id?: number; name?: string; salary?: number; } const emp: Required<Employee> = { id: 1, name: 'Bobby Hadz', salary: 1000, };

make all properties required in typescript

The code for this article is available on GitHub

The Required utility type constructs a new type with all properties of the provided type set to required.

index.ts
interface Employee { id?: number; name?: string; salary?: number; } // ๐Ÿ‘‡๏ธ type T = { // id: number; // name: string; // salary: number; // } type T = Required<Employee>;

You can see how the built-in Required type is implemented in TypeScript's Github repository.

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

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

When prefixed with a minus, the mapping modifier removes the optionality of the type's properties.

The utility type basically takes all of the properties of the provided type and removes their optionality (makes them required).

Mapping modifiers can affect optionality both ways, e.g. you can also use them to make all of the properties of a type optional by prefixing the ?: with a plus (+?:).

If you don't add a prefix, then + is assumed.

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

This is the code for the Partial utility type, which makes all of the properties in a type optional.

Notice that the only difference between the two types is the minus in front of the question mark in the Required type.

The -?: syntax removes optionality whereas, ?: (or +?:) makes all properties in the type optional.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

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.

Copyright ยฉ 2024 Borislav Hadzhiev