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
🌐
TypeScript
typescriptlang.org β€Ί play β€Ί 3-7 β€Ί syntax-and-messaging β€Ί nullish-coalescing.ts.html
TypeScript: Playground Example - Nullish Coalescing
-1; config.active = config.active ?? true; // Current solution config.name = typeof config.name === "string" ? config.name : "(no name)"; config.items = typeof config.items === "number" ? config.items : -1; config.active = typeof config.active === "boolean" ? config.active : true; // Using || operator which could give bad data config.name = config.name || "(no name)"; // does not allow for "" input config.items = config.items || -1; // does not allow for 0 input config.active = config.active || true; // really bad, always true } // You can read more about nullish coalescing in the 3.7 blog post: https://devblogs.microsoft.com/typescript/announcing-typescript-3-7/
🌐
Marius Schulz
mariusschulz.com β€Ί blog β€Ί nullish-coalescing-the-operator-in-typescript
Nullish Coalescing: The ?? Operator in TypeScript β€” Marius Schulz
August 14, 2021 - Assuming we're targeting "ES2019" or a lower language version, the TypeScript compiler will emit the following JavaScript code: value !== null && value !== void 0 ? value : fallbackValue; The value variable is compared against both null and undefined (the result of the expression void 0). If both comparisons produce the value false, the entire expression evaluates to value; otherwise, it evaluates to fallbackValue. Now, let's look at a slightly more complex example.
🌐
TypeScript
typescriptlang.org β€Ί docs β€Ί handbook β€Ί release-notes β€Ί typescript-3-7.html
TypeScript: Documentation - TypeScript 3.7
You might find yourself using ?. to replace a lot of code that performs repetitive nullish checks using the && operator.
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί typescript β€Ί nullish-coalescing-operator-in-typescript
Nullish Coalescing Operator (??) in TypeScript - GeeksforGeeks
July 23, 2025 - The Nullish Coalescing Operator is represented by two adjacent question marks (?? ): ... Note: At its core, the operator will return default_value when the variable is either null or undefined, alternatively it will return the actual variable. In the given below example we are demonstrating the use of the Nullish Coalescing Operator within a function.
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

🌐
Codeisbae
codeisbae.com β€Ί typescript-optional-chaining-nullish-coalescing
Optional Chaining and Nullish Coalescing in TypeScript | Code Is Bae
The code snippets above illustrate that the Nullish Coalescing Operator comes into play specifically for nullish values, not boolean or other data types.
🌐
Tektutorialshub
tektutorialshub.com β€Ί home β€Ί typescript β€Ί nullish coalescing operator in typescript
Nullish coalescing operator in Typescript - Tektutorialshub
March 15, 2023 - The leftExpr ?? rightExpr is the syntax of the nullish coalescing operator or typescript double question mark.
🌐
LogRocket
blog.logrocket.com β€Ί home β€Ί optional chaining and nullish coalescing in typescript
Optional chaining and nullish coalescing in TypeScript - LogRocket Blog
June 4, 2024 - For example, in Person::getUppercaseFullName() we return undefined if the full name is not defined. This way of implementing things is quite cumbersome and difficult to both read and maintain.
Find elsewhere
🌐
egghead.io
egghead.io β€Ί lessons β€Ί typescript-use-the-nullish-coalescing-operator-in-typescript
Use the Nullish Coalescing Operator in TypeScript | egghead.io
This lesson introduces the ?? operator which is known as nullish coalescing. The ?? operator produces the value on the right-hand side if (and only if) ...
Published Β  February 17, 2021
🌐
Medium
medium.com β€Ί @ambily_francis β€Ί unlocking-typescripts-nullish-coalescing-d00ef1db698a
Unlocking TypeScript’s Nullish Coalescing | by Ambily Francis | Medium
March 11, 2024 - Nullish coalescing is a feature introduced in TypeScript to handle scenarios where you want to provide a default value for a variable or expression if its current value is either `null` or `undefined`. This concept is represented by the `??` operator. Here’s a simple example to illustrate ...
🌐
TypeScript ESlint
typescript-eslint.io β€Ί rules β€Ί prefer-nullish-coalescing
prefer-nullish-coalescing | typescript-eslint
Generally expressions within mixed logical expressions intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs. If you're looking to enforce stricter conditional tests, you should consider using the strict-boolean-expressions rule. Examples of code for this rule with { ignoreMixedLogicalExpressions: false }:
🌐
DEV Community
dev.to β€Ί obinnaogbonnajoseph β€Ί optional-chaining-and-nullish-coalescing-typescript-3-7-5899
Optional Chaining and Nullish Coalescing - TypeScript 3.7!! - DEV Community
November 6, 2019 - The ?? operator can replace uses of || when trying to use a default value. For example, the following code snippet tries to fetch the volume that was last saved in localStorage(if it ever was); however, it has a bug because it uses ||.
🌐
JavaScript.info
javascript.info β€Ί tutorial β€Ί the javascript language β€Ί javascript fundamentals
Nullish coalescing operator '??'
The nullish coalescing operator isn’t anything completely new. It’s just a nice syntax to get the first β€œdefined” value of the two. We can rewrite result = a ?? b using the operators that we already know, like this: ... Now it should be absolutely clear what ?? does. Let’s see where it helps. The common use case for ?? is to provide a default value. For example, here we show user if its value isn’t null/undefined, otherwise Anonymous:
Top answer
1 of 2
5

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.)

2 of 2
3

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)
🌐
Execute Program
executeprogram.com β€Ί courses β€Ί everyday-typescript β€Ί lessons β€Ί nullish-coalescing
Everyday TypeScript: Nullish Coalescing
Learn programming languages like TypeScript, Python, JavaScript, SQL, and regular expressions. Interactive with real code examples.
🌐
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.

🌐
GitHub
github.com β€Ί microsoft β€Ί TypeScript β€Ί issues β€Ί 26578
Nullish coalescing operator (??) Β· Issue #26578 Β· microsoft/TypeScript
June 27, 2018 - export interface Configuration { // Default: "(no name)"; empty string IS valid name?: string; // Default: -1; 0 is valid items?: number; // Default: true active?: boolean; } function configureSomething(config: Configuration) { // With null-coalescing operator config.name = config.name ??...
Published Β  Aug 21, 2018
🌐
SPGuides
spguides.com β€Ί typescript-nullish-coalescing-operator
TypeScript ?? Operator
June 25, 2025 - You can chain ?? operators to provide multiple fallbacks in TypeScript. Here is an example: const envSetting = process.env.PAGE_SIZE ? Number(process.env.PAGE_SIZE) : undefined; const configSetting = undefined; const userSetting = null; const pageSize = userSetting ?? configSetting ?? envSetting ?? 10; console.log(`Page size: ${pageSize}`); // Uses the first non-nullish value
🌐
Carl Rippon
carlrippon.com β€Ί nullish-coalescing-with-react-and-typescript
Nullish coalescing with React and TypeScript
Notice the nullish coalescing operator (??). This renders the right-hand operand if the left-hand operand is null or undefined. So, it’s more precise than || and does precisely want we want in our case, resolving the free subscription bug. Yes, if you are running recent versions of React and TypeScript: