Borislav Hadzhiev
Mon Feb 21 2022·2 min read
Photo by Aziz Acharki
The "property does not exist on type union" error occurs when we try to access a property that is not present on every object in the union type. To solve the error, use a type guard to ensure the property exists on the object before accessing it.
Here is an example of how the error occurs.
type Person = { age: number; }; type Employee = { salary: number; }; function getProperty(obj: Person | Employee): number { // ⛔️ Error: Property 'age' does not exist on type 'Person | Employee'. if (obj.age) { return obj.age; } return obj.salary; }
The age
property does not exist on all of the types in the
union,
so we aren't able to access it directly.
Instead, we have to use a type guard to check if the property exists in the object before accessing it.
type Person = { age: number; }; type Employee = { salary: number; }; function getProperty(obj: Person | Employee): number { if ('age' in obj) { return obj.age; } return obj.salary; }
We used the in operator, which is a type guard in TypeScript.
The in
operator returns true
if the specified property is in the object or
its prototype chain.
const obj = { a: 'hello', }; console.log('a' in obj); // 👉️ true console.log('b' in obj); // 👉️ false
This way TypeScript is able to infer the type of the object in the if
block
and after it.
type Person = { age: number; }; type Employee = { salary: number; }; function getProperty(obj: Person | Employee): number { if ('age' in obj) { // 👇️ now `obj` is type `Person` return obj.age; } // 👇️ now `obj` is type `Employee` return obj.salary; }
age
property is contained in the passed in object, we can safely use the age
property and TypeScript is able to infer the type of obj
to be Person
.If the if
block doesn't run, then the age
property is not in the passed in
object and TypeScript infers the type of obj
to be Employee
.