saimonsez
saimonsez

Reputation: 344

Typescript assigns an empty string instead of a boolean

Given this typescript (2.7.2) interface:

export interface A {
  b?: string;
  c?: boolean;
}

This will print boolean 'false' as expected:

let a: A = {b: ''};
if (a.b && a.b.length > 0) {
  a.c = true;
} else {
  a.c = false;
}
console.log(a.c);

However, this prints an empty '' string:

let a: A = {b: ''};
a.c = a.b && a.b.length > 0;
console.log(a.c);

I'm a bit confused here. The second example should behave like the first one, right? What am I missing?

Upvotes: 3

Views: 1326

Answers (3)

Anurag Awasthi
Anurag Awasthi

Reputation: 6223

a.b && a.b.length > 0 which is equivalent to "" && false because empty string evaluates falsy. Expression "" && false evaluates to "". that is why a.c is "".

Refactor it like this,

a.c = a.b && a.b.length > 0 ? true : false

Upvotes: 6

CodingNagger
CodingNagger

Reputation: 1528

Leaning on the reply from @nrgwsth you can refactor further while keeping your structure by replacing a.b with !!a.b in your conditions like this:

let a: A = {b: ''};
a.c = !!a.b && a.b.length > 0;
console.log(a.c);

Applying !a.b converts a.b to its boolean negative, applying !!a.b gives you the positive boolean version of the evaluation.

Upvotes: 0

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249466

This is more of a Javascript truthy/falsy issue. The && operator will return the value of one of the operands. See docs:

However, the && and || operators actually return the value of one of the specified operands, so if these operators are used with non-Boolean values, they may return a non-Boolean value.

And specifically for && :

Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.

In your case "" is a falsy value, so it can be converted to false. If you want to ensure you get a boolean use !! (ie. double negation)

let a: A = {b: ''};
a.c = !!(a.b && a.b.length > 0);
console.log(a.c);

Upvotes: 4

Related Questions