How to get the properties and methods of a single type when using union type on a variable in TypeScript?

September 22, 2021 - 4 min read

In TypeScript, a Union Type is made by combining more than one type. So to access or get the properties and method of a single type when using union type on a variable, we have to narrow the variable type we need using an if conditional statement check and by using the typeof operator to check the type of the variable value in TypeScript.

This process is also called Narrowing types in TypeScript.

TL;DR

// union type declaration
let nums: string | number;

// Dynamically assign value to the variable nums
// In real life this would be a value from an API response
// Here we are just emulating the setting of the value
nums = true ? "Hello" : 1000;

if (typeof nums === "string") {
  // now we can access string type
  // methods and propreties here

  const upperCase = nums.toUpperCase(); // toUpperCase() method is a string type method
  console.log(upperCase); // HELLO
} else {
  // we can access the number type
  // methods and properties here

  const precision = nums.toPrecision(2); // toPrecision() method is a number type method
  console.log(precision); // 1.0e+3
}

For example, let's consider a variable called nums which has a union type made of both the string type and the number type like this,

// union type declaration
let nums: string | number;

Now let's try to use the methods and properties available to us in the nums variable. If you are using VSCode as your code editor then it may show a autocomplete dropdown showing the methods and properties available to us like this,

As you can see from the above image that there are only 3 methods that the VSCode editor's autocomplete dropdown is showing. This is because the nums variable has a union type which is composed of both the string and the number type and thus it can only show the methods and properties common (or union) to both the string and the number type.

But what if we need the methods and properties of string type. To do that we have to narrow down the type of the variable nums using a conditional statement check.

To do that let's use an if conditional statement check and use the typeof operator to check if the variable value is of type string like this,

// union type declaration
let nums: string | number;

nums = "Hello";

if (typeof nums === "string") {
  // now we can access string type
  // methods and propreties here
  const upperCase = nums.toUpperCase(); // toUpperCase() method is a string type method
  console.log(upperCase); // HELLO
}

As you can see from the above code that the TypeScript compiler allowed us to use the toUpperCase() string type method inside the if block since we have checked to see if the variable value is of type string before getting into the if block.

Now if we add an else block to the above if condition, the TypeScript compiler is intelligent to know that the other type we can use is the number type. So let's try to access one of the methods of the number type in the else block like this,

// union type declaration
let nums: string | number;

// Dynamically assign value to the variable nums
// In real life this would be a value from an API response
// Here we are just emulating the setting of the value
nums = true ? "Hello" : 1000;

if (typeof nums === "string") {
  // now we can access string type
  // methods and propreties here

  const upperCase = nums.toUpperCase(); // toUpperCase() method is a string type method
  console.log(upperCase); // HELLO
} else {
  // we can access the number type
  // methods and properties here

  const precision = nums.toPrecision(2); // toPrecision() method is a number type method
  console.log(precision); // 1.0e+3
}

As you can see from the above code that the TypeScript compiler allowed us to use the toPrecision() number type method on the else block which is what we want to happen.

This means we have successfully type-checked against every possible scenario which may occur during the runtime of the program 🎉.

See the above code live in codesandbox.

That's all 😃!

Feel free to share if you found this useful 😃.