With the release of Typescript 3.7 there is now support for Nullish Coalescing. However it seems like I am using it wrongly.. I have the following structure:
type myType = { ["myKeys"]?: Array<string> }
let data: myType;
data = {};
data["myKeys"] = ["index0"];
console.log(data?.["myKeys"]?.indexOf("index0")) // 0
if (data?.["myKeys"]?.indexOf("index0") ?? -1 === -1) { // returns false
} else {
console.log("returns false");
}
data["myKeys"].push("index1")
console.log(data?.["myKeys"]?.indexOf("index1")) // 1
if (data?.["myKeys"]?.indexOf("index1") ?? -1 === -1) { // returns true - why?
console.log("Why is it true");
}
Why does the ??
operator behave differently when the index of index1
is 1
while the index of index0
is 0
. Both should return false since it's !== -1
Playground link
It's a precedence issue. Your code is being evaluated as:
if (data?.["myKeys"]?.indexOf("index1") ?? (-1 === -1)) {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^−−−−−−−−−^
console.log("Why is it true");
}
but your intention is:
if ((data?.["myKeys"]?.indexOf("index1") ?? -1) === -1) {
// −^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^
console.log("Why is it true");
}
Oddly, I don't see precedence discussed in the proposal though it is mentioned in the draft spec as Jonas mentions, and it does come up in the issues.
As you can see, this is consistent with the precedence of ||
, which is its very, very near relative:
const a = 2;
const b = -1;
console.log(`${a} || ${b} === ${b}: ${a || b === b}`);
console.log(`(${a} || ${b}) === ${b}: ${(a || b) === b}`);
console.log(`${a} || (${b} === ${b}): ${a || (b === b)}`);
According to the draft spec, ??
has lower precedence than ||
(presumably just lower). (To avoid confusion, it's also not allowed in an &&
or ||
expression.)
To quote from the draft:
?? has lower precedence than ||
Or in other words, your code behaves roughly like:
data?.["myKeys"]?.indexOf("index0") || -1 === -1
And that'll be treated as:
(data?.["myKeys"]?.indexOf("index0")) || (-1 === -1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With