javascript - TypeScript - Finns det ett alternativ för att förbjuda användning av "! framför något annat än en boolean?


Jag förstår att detta kan vara ett klassiskt javascript-problem, men jag har för ofta funnit mig själv använda :

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

för att validera att detta something inte är undefined eller null i TypeScript.

Detta är mycket felbenäget! När det används på en number kommer "0" att matcha, och när det används på en enum kommer det första objektet också att matcha (som standard har det första objektet värdet "0")!

Finns det ett sätt att hantera detta i TypeScript? Finns det ett sätt att konfigurera TypeScript så att ett utropstecken inte är tillåtet framför något annat än en boolean (och any)? Skulle denna konfiguration vara meningsfull eller missar jag något trivialt?

Bör:

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

användas istället, för att validera att något är definierat eller inte? Och finns det ett sätt att upprätthålla detta i ett team?

Svar #1

Du kan använda TSLint-regeln strict-boolean-expressions för att förbjuda den här typen av saker.

Du kan se några exempel på regeln här, men detta är ett utdrag som är särskilt relevant för din fråga. Platser där regeln skulle hitta fel är markerade med ~~~ och felmeddelandet är skrivet bredvid 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.]

För att kort svara på din andra sidofråga är följande kodsnutt ett bra sätt att kontrollera om något är definierat eller inte:

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

Se här för mer information om ovanstående

Relaterade artiklar