Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript - Is there an option to disallow using "! in front of anything except a boolean?

I understand this may be a classical javascript issue, but I too often found myself using :

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

to validate that this something is not undefined or null, in TypeScript.

This is very error-prone! When used on a number "0" will match, and when used on an enum the first item will match too (by default, the first item has a value of "0")!

Is there a way to deal with this in TypeScript? Is there a way to configure TypeScript to disallow an exclamation mark in front of anything except a boolean (and any)? Would this configuration make sense or am I missing something trivial?

Should :

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

be used instead, to validate that something is defined or not? And is there a way to enforce this in a team?

like image 789
electrotype Avatar asked Mar 30 '17 14:03

electrotype


1 Answers

You can use the strict-boolean-expressions TSLint rule to disallow this sort of thing.

You can see some examples of the rule here, but this is an excerpt that's particularly relevant to your question. Places where the rule would find errors are marked with ~~~ and the error message is written next to that marking:

/*** 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.]

To answer your other side question briefly, the below code snipped is a nice way to check if something is defined or not:

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

See here for more details on the above

like image 88
JKillian Avatar answered Oct 04 '22 15:10

JKillian