Check if an Object implements an interface in TypeScript

avatar

Borislav Hadzhiev

Fri Mar 11 20223 min read

Check if an Object implements an interface in TypeScript #

Use a user-defined type guard to check if an object implements an interface in TypeScript. The user-defined type guard consists of a function, which checks if the passed in object contains specific properties and returns a type predicate.

index.ts
interface Employee { id: number; name: string; salary: number; } function isAnEmployee(obj: any): obj is Employee { return 'id' in obj && 'name' in obj && 'salary' in obj; } const emp: Employee = { id: 1, name: 'James', salary: 100, }; console.log(isAnEmployee(emp)); // 👉️ true console.log(isAnEmployee({ id: 1 })); // 👉️ false if (isAnEmployee(emp)) { // 👉️ TypeScript knows that emp is type Employee console.log(emp.id); // 👉️ 1 console.log(emp.name); // 👉️ "James" console.log(emp.salary); // 👉️ 100 }

We used a user-defined type guard to check if an object implements an interface.

The obj is Employee syntax is a type predicate where obj must be the name of the parameter the function takes.

If the isAnEmployee function returns true, TypeScript knows that the passed in value is of type Employee and allows us to access all properties and methods on the specific interface.

The example above simply checks if the passed in object contains the id, name and salary properties.

Depending on your use case, you might need to be more strict and check not only for the existence of the properties, but also for the types of the values.

This can get pretty verbose if your interface has many properties.

An alternative approach is to add a type property to the interface, for which you check instead.

index.ts
interface Employee { id: number; name: string; salary: number; type: 'Employee'; // 👈️ add type property } function isAnEmployee(obj: any): obj is Employee { // 👇️ check for type property return 'type' in obj && obj.type === 'Employee'; } const emp: Employee = { id: 1, name: 'James', salary: 100, type: 'Employee', }; console.log(isAnEmployee(emp)); // 👉️ true console.log(isAnEmployee({ id: 1 })); // 👉️ false if (isAnEmployee(emp)) { console.log(emp.id); // 👉️ 1 console.log(emp.name); // 👉️ "James" console.log(emp.salary); // 👉️ 100 console.log(emp.type); // 👉️ "Employee" }

The Employee interface has a type property with the value of Employee. This means that all objects that have a type Employee will have this property.

In our function, all we have to do is check if the passed in object has a type property that's equal to Employee.

However, note that this can get difficult to manage if you have interfaces that extend from Employee.

index.ts
interface Employee { id: number; name: string; salary: number; type: 'Employee'; // 👈️ add type property } // ⛔️ Error: Interface 'Accountant' incorrectly // extends interface 'Employee'. // Types of property 'type' are incompatible. interface Accountant extends Employee { type: 'Accountant'; }

You can't simply override the type property in the Accountant interface.

If you have to do this, you'd get to set the type property to be a string, but this would be difficult to manage if you have deeply nested structures.

User-defined type guard are very useful, especially when you have to check if an object is one of multiple types you know about in advance.

index.ts
interface Dog { bark(): void; } interface Cat { meow(): void; } const dog: Dog = { bark() { console.log('woof'); }, }; const cat: Cat = { meow() { console.log('meow'); }, }; function isDog(pet: Dog | Cat): pet is Dog { return 'bark' in pet; } function getPet(): Dog | Cat { return Math.random() > 0.5 ? dog : cat; } const pet = getPet(); if (isDog(pet)) { console.log(pet.bark()); } else { // 👉️ TypeScript knows pet is Cat console.log(pet.meow()); }

The isDog() function in the example takes a parameter of type Dog or Cat and checks if the passed in parameter is a Dog.

Notice that in the if block we are able to access dog-specific properties and in the else block, TypeScript knows that if pet isn't a Dog, then it will be of type Cat.

Use the search field on my Home Page to filter through my more than 1,000 articles.