javascript - TypeScript - Finnes det et alternativ for å ikke tillate bruk av «!»-tegnet foran noe annet enn en boolsk verdi?


Jeg forstår at dette kan være et klassisk JavaScript-problem, men jeg har altfor ofte funnet meg selv i å bruke :

if (!something) {
    //...
}

å validere at dette something ikke er undefined eller null, i TypeScript.

Dette er veldig feilutsatt! Når det brukes på et number vil "0" matche, og når det brukes på en enum vil også det første elementet matche (som standard har det første elementet verdien "0")!

Finnes det en måte å håndtere dette i TypeScript på? Finnes det en måte å konfigurere TypeScript til å ikke tillate et utropstegn foran noe annet enn en boolean (og any)? Ville denne konfigurasjonen gi mening, eller går jeg glipp av noe åpenbart?

Bør :

if (something === null || something === undefined) {
    //...
}

brukes i stedet, for å validere at noe er definert eller ikke? Og er det en måte å håndheve dette på i et team?

Svar #1

Du kan bruke TSLint-regelen strict-boolean-expressions for å forby denne typen ting.

Du kan se noen eksempler på regelen her, men dette er et utdrag som er spesielt relevant for spørsmålet ditt. Steder hvor regelen vil finne feil er merket med ~~~ og feilmeldingen er skrevet ved siden av den markeringen:

/*** PrefixUnary Expressions ***/
/*** Invalid ***/
!!numType;
  ~~~~~~~  [This type is not allowed in the operand for the '!' operator because it is a number. Only booleans are allowed.]
!strType;
 ~~~~~~~  [This type is not allowed in the operand for the '!' operator because it is a string. Only booleans are allowed.]
!objType;
 ~~~~~~~  [This type is not allowed in the operand for the '!' operator because it is always truthy. Only booleans are allowed.]
!enumType;
 ~~~~~~~~  [This type is not allowed in the operand for the '!' operator because it is an enum. Only booleans are allowed.]
!!classType;
  ~~~~~~~~~  [This type is not allowed in the operand for the '!' operator because it is always truthy. Only booleans are allowed.]
!bwrapType;
 ~~~~~~~~~  [This type is not allowed in the operand for the '!' operator because it is always truthy. Only booleans are allowed.]
!!undefined;
 ~~~~~~~~~~  [This type is not allowed in the operand for the '!' operator because it is always truthy. Only booleans are allowed.]
  ~~~~~~~~~  [This type is not allowed in the operand for the '!' operator because it is always falsy. Only booleans are allowed.]

/*** Valid ***/
!!boolFn();
!boolExpr;
!!boolType;

/*** If Statement ***/
/*** Invalid ***/
if (numType) { /* statements */ }
    ~~~~~~~                       [This type is not allowed in the 'if' condition because it is a number. Only booleans are allowed.]
if (objType) { /* statements */ }
    ~~~~~~~                       [This type is not allowed in the 'if' condition because it is always truthy. Only booleans are allowed.]
if (strType) { /* statements */ }
    ~~~~~~~                       [This type is not allowed in the 'if' condition because it is a string. Only booleans are allowed.]
if (bwrapType) { /* statements */ }
    ~~~~~~~~~                       [This type is not allowed in the 'if' condition because it is always truthy. Only booleans are allowed.]
if (strFn()) { /* statements */ }
    ~~~~~~~                       [This type is not allowed in the 'if' condition because it is a string. Only booleans are allowed.]
if (MyEnum.A) { /* statements */ }
    ~~~~~~~~                       [This type is not allowed in the 'if' condition because it is an enum. Only booleans are allowed.]
if (classType) { /* statements */ }
    ~~~~~~~~~                       [This type is not allowed in the 'if' condition because it is always truthy. Only booleans are allowed.]

For å svare kort på ditt andre sidespørsmål, er kodesnutten nedenfor en fin måte å sjekke om noe er definert eller ikke:

if (something == null) {
    // will enter here if `something === null || something === undefined`
}

Se her for mer informasjon om ovenstående

Relaterte artikler