This comparison appears to be unintentional because the types 'X' and 'Y' have no overlap

avatar
Borislav Hadzhiev

Last updated: Feb 28, 2024
5 min

banner

# This comparison appears to be unintentional because the types 'X' and 'Y' have no overlap

The error "This comparison appears to be unintentional because the types 'X' and 'Y' have no overlap" occurs when a condition is guaranteed to have the same outcome 100% of the time.

To solve the error, correct the logic in the condition or use a type assertion if TypeScript is getting confused.

this-comparison-appears-to-be-unintentional

Here are 3 examples of how the error occurs.

index.ts
const num = 30; const str = '30'; // ⛔️ Error: This comparison appears to be unintentional because the types 'number' and 'string' have no overlap. if (num === str) { console.log('success'); } // --------------------------------------------------------- const str2 = 'bobby'; // ⛔️ This comparison appears to be unintentional because the types '"bobby"' and '"hadz"' have no overlap. if (str2 === 'bobby' && str2 === 'hadz') { console.log('success'); } // --------------------------------------------------------- export enum Sizes { Small = 'S', Medium = 'M', Large = 'L', } let size: Sizes = Sizes.Medium; [1, 2].forEach((_) => { size = Sizes.Large; }); console.log(size); // 👉️ "L" // ⛔️ This comparison appears to be unintentional because the types 'Sizes.Medium' and 'Sizes.Large' have no overlap. if (size === Sizes.Large) { console.log('success'); }

# Comparing two values of a different type with strict equality

In the first example, we are trying to compare two values of a different type which is guaranteed to return false.

index.ts
const num = 30; const str = '30'; // ⛔️ Error: This comparison appears to be unintentional because the types 'number' and 'string' have no overlap. if (num === str) { console.log('success'); }

this comparison appears to be unintentional because types have no overlap

The code for this article is available on GitHub

To solve the error in this scenario:

  1. Make sure you are comparing values of compatible types.
  2. console.log the values in the condition.
  3. Make sure the outcome of the condition is not the same 100% of the time.
index.ts
const num = 30; const str = '30'; if (num === Number(str)) { console.log('success'); }

compare values of compatible types

We used the Number() constructor to convert the string to a number before comparing the values.

Now the values on the left and right-hand sides are compatible types, so the comparison works as expected.

Want to learn more about comparing values in TypeScript? Check out these resources: How to compare Objects in TypeScript,How to compare Dates in JavaScript and TypeScript,How to compare Enums in Typescript.

# Mixing up the logical AND (&&) and logical OR (||) operators

In the second example, we got the error because we used the logical AND (&&) operator instead of the logical OR (||) operator.

index.ts
const str = 'bobby'; // ⛔️ This comparison appears to be unintentional because the types '"bobby"' and '"hadz"' have no overlap. if (str === 'bobby' && str === 'hadz') { console.log('success'); }

The str variable cannot possibly have a value of bobby and hadz at the same time, so the condition is always going to return false.

To solve the error, use the logical OR (||) operator instead.

index.ts
const str = 'bobby'; if (str === 'bobby' || str === 'hadz') { console.log('success'); // 👉️ this runs }

use logical or operator to solve the error

The code for this article is available on GitHub

When the logical OR (||) operator is used in an if statement, at least one of the conditions has to be met for the if block to run.

When the logical AND (&&) operator is used in an if statement, both conditions have to be met for the if block to run.

  1. Logical OR (||) returns the value to the right if the value to the left is falsy, otherwise, the value to the left is returned.

  2. Logical AND (&&) returns the value to the left if it's falsy, otherwise, the value to the right is returned.

# Using the logical NOT (!) operator incorrectly

The error also occurs if we use the logical NOT (!) operator incorrectly when comparing values.

index.ts
const str1 = 'bobby'; const str2 = Math.random() > 0.5 ? 'bobby' : 'hadz'; // ⛔️ This comparison appears to be unintentional because // the types 'boolean' and 'string' have no overlap. if (str1 === 'bobby' && !str1 !== str2) { console.log('success'); }

Notice that we used the logical NOT (!) operator in the expression:

index.ts
!str1 !== str2

We didn't wrap the expression in parentheses, so the logical NOT (!) operator simply negates the value to the left and converts it to a boolean.

To solve the error, wrap the expression in parentheses.

index.ts
const str1 = 'bobby'; const str2 = Math.random() > 0.5 ? 'bobby' : 'hadz'; // ✅ wrapped the expression in parentheses if (str1 === 'bobby' && !(str1 !== str2)) { console.log('success'); }

use logical not operator correctly

The code for this article is available on GitHub

Now we negate the expression str1 !== str2 rather than just the value stored in the str1 variable, so everything works as expected.

# Working around TypeScript's limitations (e.g. with Enums)

In some cases, the issue is not in our code but with limitations in the TypeScript compiler.

index.ts
export enum Sizes { Small = 'S', Medium = 'M', Large = 'L', } let size: Sizes = Sizes.Medium; [1, 2].forEach((_) => { size = Sizes.Large; }); console.log(size); // 👉️ "L" // ⛔️ This comparison appears to be unintentional because the types 'Sizes.Medium' and 'Sizes.Large' have no overlap. if (size === Sizes.Large) { console.log('success');// 👉️ this runs }

The code sample shows that the size variable gets set to Sizes.Large in the forEach() method but TypeScript doesn't know about it.

You can read more about comparing enums in this article.

# Use a type assertion to solve the error

In this case, the easiest way to solve the error is to use a type assertion.

index.ts
export enum Sizes { Small = 'S', Medium = 'M', Large = 'L', } let size: Sizes = Sizes.Medium; [1, 2].forEach((_) => { size = Sizes.Large; }); console.log(size); // 👉️ "L" // ✅ Use type assertion if ((size as Sizes) === Sizes.Large) { console.log('success'); // 👉️ this runs }

use type assertion to solve the error

The code for this article is available on GitHub

We used a type assertion to type the size variable as Sizes.

Sometimes we have information about the type of a value that TypeScript can't know about.

By using a type assertion, we effectively tell TypeScript that the size variable is guaranteed to have a type of Sizes, so don't worry about it.

We could have also used a type assertion when declaring the size variable.

index.ts
export enum Sizes { Small = 'S', Medium = 'M', Large = 'L', } // 👇️ Use type assertion here 👇️ let size: Sizes = Sizes.Medium as Sizes; [1, 2].forEach((_) => { size = Sizes.Large; }); console.log(size); // 👉️ "L" if (size === Sizes.Large) { console.log('success'); // 👉️ this runs }

This is a bit better in this case because we wouldn't have to repeat ourselves every time we use the size variable in a comparison.

In this case, we solved the error by convincing TypeScript that the condition is not guaranteed to have the same outcome 100% of the time.

# Forgetting to access a Property on an Object

Here is another example of how the error occurs.

index.ts
// ⛔️ src/index.ts:19:5 - error TS2367: // This comparison appears to be unintentional because the types // 'ProcessEnv' and 'string' have no overlap. if (process.env === 'development') { console.log('dev'); }

We are trying to compare the process.env object to the string development which causes the issue.

To solve the error, we have to make sure that the values on the left-hand and right-hand sides are of compatible types.

In this case, we have to access a property on the process.env object and compare the property to the string.

index.js
if (process.env.NODE_ENV === 'production') { console.log('prod'); } else if (process.env.NODE_ENV === 'development') { console.log('dev'); } else { console.log(process.env.NODE_ENV); }
The code for this article is available on GitHub

The NODE_ENV property is just an example.

However, if the property returns a value of type string, the comparison is valid.

# Things to note when solving the error

Make sure:

  1. That you are comparing values of compatible types.
  2. console.log the values in the condition.
  3. The outcome of the condition is not the same 100% of the time.
  4. You haven't mixed up the logical AND (&&) and the logical OR (||) operators.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

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.