Typescript error This condition will always return 'true' since the types have no overlap

114,727

Solution 1

Consider the standalone expression:

(this.frType!="Child" || this.frType!="Infant")

If frType is Child, the second part will be true, so the expression will evaluate to true. If frType is Infant, then the first part will be true, so the expression will evaluate to true. If frType is neither Child nor Infant, then the first part will be true, and the expression will, again, evalute to true - the logic is faulty, it'll always resolve to true.

(If you add additional || conditions for Grandchild and Cousin, the same thing keeps happening - it'll always resolve to true)

Either use && instead:

|| (age<=5 && (
   this.frType!="Child" 
   && this.frType!="Infant" 
   && this.frType!="Grandchild"
   && this.frType!="Cousin"
 ))

Or, to make the logic easier to follow, you might consider using an array, and use .includes:

const kidsFiveAndUnder = ['Child', 'Infant', 'Grandchild', 'Cousin'];
// ...
|| (age <= 5 && !kidsFiveAndUnder.includes(this.frType))

Solution 2

Maybe i can help someone with this.

In my case the error was triggered by:

*ngIf="fooArray.length === 0"

so i modified it to be:

*ngIf="fooArray.length < 1"

Makes no sense to me, but it works.

Solution 3

Define the data types of all your variables explicitly.

For example, this code has the same error mentioned in the thread title and I fixed by defining the data types of the variables explicitly.

From:

const selectedLangCulture = "en"; // or "ar-SA"
const direction = "rtl";
const languageChanged =
  (direction === "rtl" && selectedLangCulture === "en") ||
  (direction === "ltr" && selectedLangCulture === "ar-SA");

To:

const selectedLangCulture: string = "en"; // Put the datatype string.
const direction: string = "rtl"; // Put the datatype string.
const languageChanged =
  (direction === "rtl" && selectedLangCulture === "en") ||
  (direction === "ltr" && selectedLangCulture === "ar-SA");

Solution 4

I struggled with this problem recently. Sharing my experience here

Basically IDE does not allow to compare an object.enum with a string. As a solution, a method in the component.ts is added to compare the enum

Details :

export enum Status {
     NEW,
     PROGRESS,
     FINISHED
}

export interface Model {
   id : number;
   name : string;
   status : Status
}

Now in the component.html, I was trying to compare the model status

<div *ngFor="let m of modelItems" >
      <i *ngIf="m.status === 'NEW'" class="icon-new"></i>
</div>

Error : This condition will always return 'false' since the types 'Status' and 'string' have no overlap.ngtsc(2367)

I also tried defining the status enum in the component.ts and used that for comparison

public StatusEnum = Status; 

<div *ngFor="let m of modelItems" >
      <i *ngIf="StatusEnum[m.status] === 'NEW'" 
        class="icon-new"></i>
</div>

With the above solution, there is no IDE error, but the condition never true, as the enum[value] give a numeric value.

The next option I tried was as follows

<div *ngFor="let m of modelItems" >
      <i *ngIf="m.status=== StatusEnum[StatusEnum.NEW]" class="icon-new"></i>
    </div>

But ended up with the error again in the IDE

Error : This condition will always return 'false' since the types 'Status' and 'string' have no overlap.ngtsc(2367)

Finally what solved the issue it implement a method in the component.ts

Solution

component.ts

public StatusEnum = Status; //To refer in the HTML

 checkStatus(m: Model, status: Status): boolean {
    return Status[m.status] as unknown === status;
  } 

Note : Status[m.status] as unknown

HTML

<div *ngFor="let m of modelItems" >
       <i *ngIf="checkStatus(m,StatusEnum.NEW)" 
       class="icon-new"></i>
  </div>    

Solution 5

In my case, I simply had to rebuild my app because the type definitions got briefly out of sync.

Share:
114,727
alim1990
Author by

alim1990

Updated on February 05, 2022

Comments

  • alim1990
    alim1990 over 2 years

    I having this condition on a form group:

    if((age>17 && (this.frType=="Infant")) 
    || (age>40 && this.frType=="Grandchild")
    || (age<=5 && 
       (this.frType!="Child" 
       || this.frType!="Infant" 
       || this.frType!="Grandchild" || this.frType!="Cousin")))
    

    It contain 3 main conditions:

    1. If a person aged 17, cannot be set to infant
    2. If a person is bigger than 40, he cannot be a grandchild
    3. If a person is less than 5 years, he should be child, infant, grandchild or cousin.

    If one of these conditions is true, I will send an error message.

    The error I am receiving is:

    [ts] This condition will always return 'true' since the types '"Child"' and '"Infant"' have no overlap. [2367]

    On this part of the if condition`:

    || this.frType!="Infant" || this.frType!="Grandchild" || this.frType!="Cousin")))
    

    I am using the exact condition in a different component, and it does not show an error.

    if((age>17 && (this.family_relation_type=="Infant")) 
    || (age>40 && this.family_relation_type=="Grandchild")
    || (age<=5 && 
       (this.family_relation_type!="Child" || 
        this.family_relation_type!="Infant" || 
        this.family_relation_type!="Grandchild" || 
        this.family_relation_type!="Cousin")))
    

    Here is how I am calculating the age in both components:

    let timeDiff = Math.abs(Date.now() - this.formGroup.controls['dob'].value);
    let age = Math.floor((timeDiff / (1000 * 3600 * 24))/365);
    
  • Andy
    Andy over 3 years
    It's better to leave out the Angular *ngIf stuff, it's just noise that's not relevant to the TypeScript issue at hand.
  • Adépòjù Olúwáségun
    Adépòjù Olúwáségun over 3 years
    Thanks for being explicit ✌🏼
  • alvarosmh
    alvarosmh about 3 years
    I know it is not part of the TS issue, Im just trying to help anyone with the same scenario.
  • MindRoasterMir
    MindRoasterMir over 2 years
    Strange but very good. It solved my problem thanks.