alim1990
alim1990

Reputation: 4972

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

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);

Upvotes: 83

Views: 337137

Answers (8)

Anupam Haldkar
Anupam Haldkar

Reputation: 1085

Mostly, In typescript base architecture, The most common error will come when you do not have a proper type conversion while comparing or converting data.

  1. Check the data type that you are manipulating.
  2. The Data coming from the request is correctly converted to the desired one.
  3. Check the conditions of statements.

Upvotes: 0

Shawn Lee
Shawn Lee

Reputation: 59

it look like typescript help to "simplify the Logic"

  • so it help remove the unnecessary Logic code.
  • '||' mean one true -> all true, so comparison after is not necessary
  • '&&' mean one false -> all false, so comparison is a must

go trough the code below will have better understanding.

code run on js typescript

Upvotes: 3

doğukan
doğukan

Reputation: 27451

In my case, I was using a type named type for the button element with React.ComponentPropsWithRef<'button'>

type ButtonProps = {
  type?: 'submit' | 'button' | 'link'; // ❌
} & React.ComponentPropsWithRef<'button'>;

the type was overridden because React.ComponentPropsWithRef<'button'> had a type in it also. I replaced it with elementType and the problem is solved.

type ButtonProps = {
  elementType?: 'submit' | 'button' | 'link'; // ✅
} & React.ComponentPropsWithRef<'button'>;

Upvotes: 2

jfk
jfk

Reputation: 5297

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>    

Upvotes: 10

TheScrappyDev
TheScrappyDev

Reputation: 4963

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

Upvotes: 1

Mohammed Osman
Mohammed Osman

Reputation: 4246

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");

Upvotes: 6

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.

Upvotes: 17

CertainPerformance
CertainPerformance

Reputation: 370879

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))

Upvotes: 81

Related Questions