To narrow down the properties and methods of an object with union type we can use the in
operator in TypeScript.
TL;DR
// Editor type
type Editor = {
name: string;
};
// Admin type
type Admin = {
name: string;
role: string;
};
// function with parameter of user with
// union type composed of `Editor` and `Admin` type
function showRole(user: Editor | Admin) {
// use the `in` operator to narrow down to the `Admin` type
// since "role" property only exists in `Admin` type
if ("role" in user) {
console.log(user.role);
} else {
console.log("No user roles assigned");
}
}
For example, let's make a type called Editor
with a name
property having the type of string
and another type called Admin
having name
and role
having the type of string
like this,
// Editor type
type Editor = {
name: string;
};
// Admin type
type Admin = {
name: string;
role: string;
};
Now let's make a function called showRole
with a parameter of user
with a union type composed of both the Editor
and Admin
types.
It may look like this,
// Editor type
type Editor = {
name: string;
};
// Admin type
type Admin = {
name: string;
role: string;
};
// function with parameter of user with
// union type composed of `Editor` and `Admin` type
function showRole(user: Editor | Admin) {
// cool code here... 🥳
}
Now the aim of the above function should be to show the role of the user to the console that will be passed down to the function parameter.
So let's try to access the role
property in the user
variable.
It can be done like this,
// Editor type
type Editor = {
name: string;
};
// Admin type
type Admin = {
name: string;
role: string;
};
// function with parameter of user with
// union type composed of `Editor` and `Admin` type
function showRole(user: Editor | Admin) {
// this will be an error ❌ 🤯.
console.log(user.role); // Property 'role' does not exist on type 'Editor | Admin'.
}
As soon we try to access the role
property from the user
object variable, the TypeScript compiler shows us an error saying Property 'role' does not exist on type 'Editor | Admin'.
This is because TypeScript doesn't know which type to use for the user
object variable when we access the role
property. This is an error caused because the user
object variable has a union type with Editor
and Admin
type and we haven't properly narrowed down the type we need to use here.
- To narrow down to the correct type let's use the
in
operator. Thein
operator will check if a property or a method exists in a given object.
Since we need to show the role
property which is present only in the Admin
type, we can use the in
operator and check to see if the role
property exits in the given object.
It can be done like this,
// Editor type
type Editor = {
name: string;
};
// Admin type
type Admin = {
name: string;
role: string;
};
// function with parameter of user with
// union type composed of `Editor` and `Admin` type
function showRole(user: Editor | Admin) {
// use the `in` operator to narrow down to the `Admin` type
// since "role" property only exists in `Admin` type
if ("role" in user) {
console.log(user.role);
} else {
console.log("No user roles assigned");
}
}
Now inside the if
block we can access all the properties and methods of the Admin
type and the TypeScript compiler won't show the errors which is what we want to happen. 🥳
See the above code live in codesandbox.
Top comments (0)