Vyhledávání na webu

javascript - Chyba v TypeScriptu: Tato podmínka vždy vrátí 'true', protože typy se nepřekrývají


Mám tento stav na formuláři skupiny:

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

Obsahuje 3 hlavní podmínky:

  1. Pokud je osoba ve věku 17 let, nelze ji nastavit na infant
  2. Pokud je osoba větší než 40, nemůže být vnukem
  3. Pokud je osoba mladší pěti let, měla by být child, infant, grandchild nebo cousin.

Pokud je některá z těchto podmínek pravdivá, pošlu chybovou zprávu.

Chyba, kterou dostávám, je:

[ts] Tato podmínka vždy vrátí 'true', protože typy 'Child' a 'Infant' se nepřekrývají. [2367]

Na této části podmínky if:

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

Používám přesně stejnou podmínku v jiné komponentě a nezobrazuje se žádná chyba.

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

Zde je způsob, jak počítám věk v obou složkách:

let timeDiff = Math.abs(Date.now() - this.formGroup.controls['dob'].value);
let age = Math.floor((timeDiff / (1000 * 3600 * 24))/365);

Odpověď č. 1

Zvažte samostatný výraz:

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

Pokud je frType Child, druhá část bude pravdivá, takže výraz bude vyhodnocen jako true. Pokud je frType Infant, pak první část bude pravdivá, takže výraz bude vyhodnocen jako true. Pokud frType není ani Child ani Infant, pak první část bude pravdivá a výraz se opět vyhodnotí jako true - logika je chybná, vždy se vyhodnotí jako true.

(Pokud přidáte další podmínky || pro Grandchild a Cousin, stane se to samé - vždy se to vyhodnotí jako true)

Místo toho použijte &&:

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

Nebo, abyste učinili logiku snazší k pochopení, můžete zvážit použití pole a použít .includes:

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

Odpověď č. 2

Možná s tímto mohu někomu pomoci.

V mém případě byla chyba vyvolána:

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

tak jsem to upravil na:

*ngIf="fooArray.length < 1"

Pro mě to nedává smysl, ale funguje to.

Odpověď č. 3

Nedávno jsem měl s tímto problémem potíže. Sdílím zde svou zkušenost

V podstatě IDE neumožňuje porovnávat object.enum s řetězcem. Jako řešení je do component.ts přidána metoda pro porovnání enumu.

Podrobnosti :

export enum Status {
     NEW,
     PROGRESS,
     FINISHED
}

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

Teď v component.html jsem se snažil porovnat stav modelu

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

Také jsem zkoušel definovat výčet stavů v component.ts a použít ho pro porovnání

public StatusEnum = Status; 

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

S výše uvedeným řešením není chyba v IDE, ale podmínka nikdy není pravdivá, protože enum[value] dává číselnou hodnotu.

Další možnost, kterou jsem vyzkoušel, byla následující

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

Ale nakonec se v IDE opět objevil chyba

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

Nakonec to, co vyřešilo problém, bylo implementovat metodu v souboru component.ts

Řešení

component.ts

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

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

Poznámka: Stav[m.status] jako neznámý

HTML

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

Související články