The nullish coalescing operator DOES NOT apply to this case:

The nullish coalescing (??) operator is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.

See the docs

In this case you have a simple union of type Day | 0, you just have to check manually:

for (let i = 0; i < 4; i++) {
  const item = daysArray[i];

  if (typeof item === "number") {
    console.log(0);
  } else {
    console.log(item.dayNumber);
  }
} 
Answer from Nullndr on Stack Overflow
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Operators › Nullish_coalescing
Nullish coalescing operator (??) - JavaScript | MDN
The nullish coalescing operator treats undefined and null as specific values. So does the optional chaining operator (?.), which is useful to access a property of an object which may be null or undefined.
🌐
TypeScript
typescriptlang.org › play › 3-7 › syntax-and-messaging › nullish-coalescing.ts.html
TypeScript: Playground Example - Nullish Coalescing
The nullish coalescing operator is an alternative to || which returns the right-side expression if the left-side is null or undefined. In contrast, || uses falsy checks, meaning an empty string or the number 0 would be considered false.
Discussions

typescript - Nullish Coalescing is not working in this case - Stack Overflow
In the following code I want to print out the "dayNumber" property, in case the item is an object otherwise It should print out the number 0. I can't get rid of the error and I don't unde... More on stackoverflow.com
🌐 stackoverflow.com
Nullish Coalescing Operator vs Logical OR
They are different, if you want value=0 to fall back to 1 you should use || otherwise use ?? More on reddit.com
🌐 r/typescript
4
2
July 13, 2022
Why does the nullish coalescing operator not work as a typeguard in typescript? - Stack Overflow
With Typescript 3.7 the nullish coalescing operator was introduced. It would seem to be the perfect type guard for cases like const fs = (s: string) => s const fn = (n: number) => n let a: ... More on stackoverflow.com
🌐 stackoverflow.com
Nullish coalescing assignment operator doesn't work correctly with logical operators
Bug Report Using the nullish coalescing assignment operator ??= on a logical statement which contains a logical operator (&& or ||) fails to narrow the type, even though using the nullish c... More on github.com
🌐 github.com
2
January 12, 2022
🌐
TypeScript
typescriptlang.org › docs › handbook › release-notes › typescript-3-7.html
TypeScript: Documentation - TypeScript 3.7
The nullish coalescing operator is another upcoming ECMAScript feature that goes hand-in-hand with optional chaining, and which our team has been involved with championing in TC39.
Top answer
1 of 4
1

The nullish coalescing operator DOES NOT apply to this case:

The nullish coalescing (??) operator is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.

See the docs

In this case you have a simple union of type Day | 0, you just have to check manually:

for (let i = 0; i < 4; i++) {
  const item = daysArray[i];

  if (typeof item === "number") {
    console.log(0);
  } else {
    console.log(item.dayNumber);
  }
} 
2 of 4
1

The nullish coalescing does not apply in this case, here is documentation of nullish coalescing with examples of how it's supposed to be used: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing

The reason why your code is giving red squiggly is because the element at daysArray[i] might be either a number or an object which has the shape of the Day interface. so trying to access daysArray[i].dayNumber is not entirely correct, first you have to check that it's an object and not a number. this way typescript compiler will infer the type of daysArray[i] to be of type Day and will allow you to access dayNumber property.

Here is a working example:

type Day = {
  dayNumber: number;
  color: string;
  isBooked: boolean;
};

const myDay: Day = {
  dayNumber: 12,
  color: "blue",
  isBooked: false
};

const daysArray: (Day | 0)[] = [0, 0, 0, myDay];

for (let i = 0; i < daysArray.length; i++) {
  const element = daysArray[i];
  if(typeof element === 'object') {
    console.log(element.dayNumber);
  }
}

Please refer to the official documentation for type narrowing: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#typeof-type-guards

🌐
GeeksforGeeks
geeksforgeeks.org › typescript › nullish-coalescing-operator-in-typescript
Nullish Coalescing Operator (??) in TypeScript - GeeksforGeeks
July 23, 2025 - The nullish coalescing (??) operator is a logical operator in TypeScript that returns its right-hand side operand if the left-hand side operand is null or undefined; otherwise, it returns the left-hand side operand.
🌐
Reddit
reddit.com › r/typescript › nullish coalescing operator vs logical or
r/typescript on Reddit: Nullish Coalescing Operator vs Logical OR
July 13, 2022 -

Take this interface for example

interface Item {
  value?: number
}

Which among the two do you prefer if you will be accessing the value property of an item and why?

console.log(item.value ?? 1.00) // 1.00 is the fallback value
console.log(item.value || 1.00) // 1.00 is the fallback value

Personally, I prefer to use the nullish coalescing operator ?? for fallback values since it's more explicit and it sames me from the weird falsy values that JavaScript has.

Find elsewhere
🌐
TypeScript ESlint
typescript-eslint.io › rules › prefer-nullish-coalescing
prefer-nullish-coalescing | typescript-eslint
Because the nullish coalescing operator only coalesces when the original value is null or undefined, it is much safer than relying upon logical OR operator chaining ||, which coalesces on any falsy value.
🌐
W3Schools
w3schools.com › jsref › jsref_oper_nullish.asp
W3Schools.com
The ?? operator returns the right operand when the left operand is nullish (null or undefined), otherwise it returns the left operand.
Top answer
1 of 1
6

I spent a long time trying to write out the mechanical explanation for why particular expressions like expr1 || expr2 && expr3 act as type guards in certain situations and not in others. It ended up becoming several pages and still didn't account for all the cases in your examples. If you care you can look at the code implemented for expression operators in microsoft/TypeScript#7140.


A more high-level explanation for why this limitation and ones like it exist: when you, a human being, sees a value of a union type, you can decide to analyze it by imagining what would happen if the value were narrowed to each member of that type, for the entire scope where that value exists. If your code behaves well for each such case analysis, then it behaves well for the full union. This decision is presumably made based on how much you care about the behavior of the code in question, or some other cognitive process that we cannot hope to reproduce by a compiler.

The compiler could possibly do this analysis all the time, for every possible union-typed expression it encountered. We could call this "automatic distributive control flow analysis" and it would have the benefit of nearly always producing the type guard behavior you want. The drawback is that the compiler would require more memory and time than you'd be willing to spend, and possibly more than humanity is able to spend due to the combinatorial explosion that happens as each additional union-typed expression has a multiplicative effect on required resources. Exponential-time algorithms don't make for good compilers.

At times I've wanted to be able to hint to the compiler that a particular union-typed value in a particular scope should be analyzed this way, and I even filed a request for such "opt-in distributive control flow analysis", (see microsoft/TypeScript#25051), but even this would require a lot of development effort to implement and would deviate from the TS design goals of enabling JS design patterns without requiring the developer to think too hard about control flow analysis.

So in the end, what TypeScript language designers do is to implement heuristics that perform such analysis in limited scopes that enable conventional and idiomatic JavaScript coding patterns. If code like (a ?? null) && fs(a) is not considered idiomatic and conventional enough for the language designers (this is partially subjective and partially depending on examining a corpus of real-world code), and if implementing it would result in a major compiler performance penalty, then I wouldn't expect the language to support it.

Some examples:

  • UPDATE FOR TS4.4; the following is fixed in microsoft/TypeScript#44370 microsoft/TypeScript#12184: support "saving" the result of a type guard into a constant (like your something example) for later use. This is an open suggestion marked as "revisit" with the ominous proclamation by a language architect that it would be difficult to do it in a performant manner. This might be idiomatic, but it might be hard to implement effectively.

  • microsoft/TypeScript#37258: support successive type guards where narrowings are performed on multiple correlated variables at once. It's closed as too complex because to avoid an exponential-time algorithm you'd need to hardcode it to some small number of checks which wouldn't be very beneficial in general. The suggestion by the language maintainers: use more idiomatic checks.


So that's the closest I can get to an authoritative or official answer on this. Hope it helps; good luck!

🌐
GeeksforGeeks
geeksforgeeks.org › javascript › nullish-coalescing-assignment-operator-in-javascript
Nullish Coalescing Assignment (??=) Operator in JavaScript - GeeksforGeeks
July 23, 2025 - Only if the value of x is nullish then the value of y will be assigned to x that means if the value of x is null or undefined then the value of y will be assigned to x.
🌐
Medium
medium.com › @gabrielairiart.gi › advanced-javascript-use-of-nullish-coalescing-and-optional-chaining-and-for-efficient-coding-7d1d3fe3eedf
Advanced JavaScript: Use of Nullish Coalescing ?? and Optional Chaining and ?. for Efficient Coding | by Gabriela Iriart | Medium
March 22, 2024 - Combining with Non-Nullable Types: In TypeScript, combining these operators with non-nullable types without proper type checks can lead to type assertion errors. Always ensure your type assumptions align with your usage of these operators. By being aware of these common mistakes, you can more effectively leverage Nullish Coalescing ...
🌐
freeCodeCamp
freecodecamp.org › news › javascript-advanced-operators
Advanced JavaScript Operators – Nullish Coalescing, Optional Chaining, and Destructuring Assignment
January 4, 2024 - By using the nullish coalescing operator, you will only replace exactly null and undefined values with the right-hand value.
🌐
DEV Community
dev.to › oliverjumpertz › javascript-quick-tip-the-nullish-coalescing-operator-1b8e
JavaScript Quick Tip: The Nullish Coalescing Operator - DEV Community
November 3, 2022 - The nullish coalescing operator works nearly identical to the logical OR, but it only reacts to null and undefined.
🌐
GitHub
github.com › microsoft › TypeScript › issues › 48473
Nullish coalescing assignment operator doesn't work correctly with logical operators · Issue #48473 · microsoft/TypeScript
January 12, 2022 - Using the nullish coalescing assignment operator ??= on a logical statement which contains a logical operator (&& or ||) fails to narrow the type, even though using the nullish coalescing operator ?? works correctly. declare function acceptBoolean (s: boolean): void declare let x: boolean | null, y: boolean | null; x = x ?? (4 < 3 && 3 < 4); acceptBoolean(x); // narrowed correctly y ??= 4 < 3 && 3 < 4; acceptBoolean(y); // error · Playground. TypeScript version 4.6.2 ·
Published   Mar 29, 2022
🌐
Medium
medium.com › @enayetflweb › understanding-typescript-operators-ternary-nullish-coalescing-and-optional-chaining-a69b8d9bbb35
Understanding TypeScript Operators: Ternary, Nullish Coalescing, and Optional Chaining | by Md Enayetur Rahman | Medium
May 5, 2024 - Nullish Coalescing Operator: The nullish coalescing operator (??) is used to provide a default value when dealing with null or undefined variables. Unlike the ternary operator, it specifically targets null or undefined values.
🌐
Nicotsou
nicotsou.com › tltr-typescript-nulish-coalescing
A Guide To Understand The Nullish Coalescing (??) Operator
December 2, 2022 - Nullish Coalescing allows you to “fall back” to a default value when dealing with the nullable values.
🌐
daily.dev
daily.dev › home › blog › webdev › nullish coalescing operator (??) in javascript - what is it and how to use it?
Nullish Coalescing Operator (??) In JavaScript - What Is It And How To Use It?
November 1, 2021 - The Nullish Coalescing Operator allows us to check if a value is `null` or `undefined`, and provide a fallback value if that is the case.