Why does this code throw a Typescript error?
const foo: number | undefined = 22
function bar(x: Date | undefined) {
!!x && console.log(x) || console.log('x is undefined')
}
bar(foo && new Date())
^^^^^^^^^^^^^^^^^
TS2345: Argument of type '0 | Date' is not assignable to parameter of type 'Date | undefined'. Type 'number' is not assignable to type 'Date'
Seems like there are two cases:
foo
is anumber
→foo && new Date()
is of typeDate
foo
isundefined
→foo && new Date()
is of typeundefined
Where does the 0
type come from here?
CodePudding user response:
The only case where foo && new Date()
is false
is when foo is 0
. 0
is a falsy value so Logical AND (&&) will return the first falsy value that makes the condition false which is 0
.
If foo was any number apart from zero it would be truthy and the Date
object, the last truthy value would instead be returned.
This means foo && new Date
can be only ever either 0
, a Date
or undefined
whereas your function is typed only for a Date
or undefined
.
CodePudding user response:
So there is a case when foo is falsy. Since it is a number, only falsy
value possible is 0.
Here is a quote from the &&
docs:
More generally, the operator returns the value of the first falsy operand encountered when evaluating from left to right, or the value of the last operand if they are all truthy.
That's why the below two statements return 0.
console.log(0 && 1);
console.log(0 && new Date());
The reason you do not get any error with regards to undefined
is because undefined
type is assignable to anything.