Check if a Property exists in an Object in TypeScript

avatar
Borislav Hadzhiev

Last updated: Feb 27, 2024
4 min

banner

# Check if a Property exists in an Object in TypeScript

To check if a property exists in an object in TypeScript:

  1. Mark the property as optional in the object's type.
  2. Use a type guard to check if the property exists in the object.
  3. If accessing the property in the object doesn't return a value of undefined, it exists in the object.
index.ts
type Employee = { name?: string; department?: string; country?: string; }; const emp: Employee = {}; // ✅ Explicitly checking if (emp.department !== undefined) { console.log(emp.department.toLowerCase()); // now string } // ✅ Using optional chaining console.log(emp.department?.toLowerCase());

check if property exists in object in typescript

The code for this article is available on GitHub

Note that we used a question mark to set the properties in the Employee type to optional.

This means that the properties we marked as optional can either have a value of undefined, or a value of type string.

# When you don't know all of the object's properties ahead of time

If you don't have all of the property names in the object in advance, use an index signature.

index.ts
type Employee = { [key: string]: string; }; const emp: Employee = {}; // ✅ Explicitly checking if (emp.department !== undefined) { console.log(emp.department.toLowerCase()); // now string } // ✅ Using optional chaining console.log(emp.department?.toLowerCase());

using index signature when setting object type

The code for this article is available on GitHub

The {[key: string]: string} syntax is an index signature and is used when we don't know all of the object's properties ahead of time, but know the shape of the values.

# Make sure the property is compatible with the object's type

In either scenario, you can only check if a property exists in a TypeScript object if the property is compatible with the object's type.

index.ts
type Employee = { name?: string; department?: string; country?: string; }; const emp: Employee = {}; // ⛔️ Property 'randomkey' does not exist on type 'Employee'. if (emp.randomkey !== undefined) { }

The Employee type doesn't have a randomkey property, so we aren't able to check if it exists in the object.

# Check if accessing the key returns a value of undefined

The best way to check for a key's existence in TypeScript is to explicitly check if accessing the specific key in the object returns a value of undefined.

index.ts
type Employee = { name?: string; department?: string; country?: string; }; const emp: Employee = {}; // 👇️ (property) department?: string | undefined emp.department // ✅ Explicitly checking if (emp.department !== undefined) { console.log(emp.department.toLowerCase()); }

check if accessing key returns value of undefined

The code for this article is available on GitHub

The department property has a type of string or undefined because it's marked as optional.

However, in the if statement, its type is string. This is called a type guard in TypeScript.

We can use any string-specific built-in methods in the if statement because TypeScript knows that if the department property isn't undefined, then it is a string.

Note that the if statement wouldn't run if the property is explicitly set to undefined in the object.

Alternatively, you can use optional chaining (?.).

# Check if a Property exists in an Object using optional chaining (?.)

You can also use the optional chaining (?.) operator to check if a property exists in an object.

index.ts
type Employee = { address?: { country?: string; city?: string; }; }; const emp: Employee = {}; // ✅ Using optional chaining console.log(emp.address?.country?.toLowerCase()); console.log(emp.address?.city?.toLowerCase()); if (emp.address?.country !== undefined) { // ✅ Now emp.address.country is string console.log(emp.address.country.toLowerCase()); }

check if property exists in object using optional chaining

The code for this article is available on GitHub

If the property exists in the object, the optional chaining (?.) operator will return the corresponding value, otherwise, the operator short-circuits returning undefined.

This is very convenient when you want to quickly check if a property exists in an object inline, e.g. to call a built-in method.

You can also use this approach to check for the existence of deeply nested properties in an object.

I've also written an article on how to get an object's key by value in TS.

# Check if a Property exists in an Object using in and hasOwnProperty

You might see examples online that use the in operator or the hasOwnProperty method to check for a key's existence in an object.

index.ts
type Employee = { name?: string; department?: string; country?: string; }; const emp: Employee = {}; if ('department' in emp) { // 👇️ (property) department?: string | undefined console.log(emp.department); } if (emp.hasOwnProperty('department')) { // 👇️ (property) department?: string | undefined console.log(emp.department); }
The code for this article is available on GitHub

The in operator returns true if the specified key is in the object or its prototype chain.

However, note that the type of the department property in the if block is still string | undefined.

This is because we might have explicitly set the department key in the object to have a value of undefined.

This would work in a different way if you use an index signature like {[key: string]: string}.

index.ts
type Employee = { [key: string]: string; }; const emp: Employee = {}; if ('department' in emp) { // 👇️ emp.department is string console.log(emp.department); } if (emp.hasOwnProperty('department')) { // 👇️ emp.department is string console.log(emp.department); }

The index signature {[key: string]: string} means that when the object is indexed with a string key, it will always return a value of type string.

This is why the in operator and the hasOwnProperty method are able to serve as type guards and determine the type of the department property to be a string in the if statements.

The hasOwnProperty method is different from the in operator because it checks if the property exists directly on the object (excluding its prototype chain).

index.ts
type Employee = { [key: string]: string; }; const emp: Employee = {}; if (emp.hasOwnProperty('department')) { // 👇️ emp.department is string console.log(emp.department); }

If ESLint is giving you an error, you can get around it by calling the method on the Object.prototype.

index.ts
type Employee = { [key: string]: string; }; const emp: Employee = {}; if (Object.prototype.hasOwnProperty.call(emp, 'department')) { // 👇️ emp.department is string console.log(emp.department); }

Which approach you pick is a matter of personal preference. I'd go with explicitly checking if accessing the property in the object returns a value of undefined as it is the easiest to read and the most explicit approach.

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.