The ?. Operator in TypeScript: How It Works and What It's Actually Called

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: The Question That Haunts Beginners

\n

Have you ever written code in TypeScript and gotten an error like Cannot read property 'name' of undefined? A familiar pain, right? Especially when working with data coming from a server or deeply nested objects. It's in moments like these that the question arises: "Is there an operator in TypeScript that allows you to safely access properties without fear of everything crashing?"

\n

On Stack Overflow, this question has gathered thousands of views. And the answer is yes, such an operator exists. Moreover, it exists in JavaScript (starting from ES2020), and in TypeScript it works "out of the box." It's called optional chaining, and it looks like the familiar ?.. In this article, we will not only tell you how to use it but also look under the hood: how the TypeScript compiler transforms this elegant syntax into safe JavaScript code.

\n\n

What Is the ?. Operator Called in TypeScript?

\n

Let's start with the main point. In the developer community, this operator is called by different names:

\n
    \n
  • Optional chaining — the official name in the ECMAScript specification.
  • \n
  • Safe navigation operator — borrowed from other languages like C# and Swift.
  • \n
  • Null-conditional operator — found in Microsoft documentation.
  • \n
\n

But the essence is the same: ?. allows you to access an object's property, and if the object is null or undefined, instead of an error, we simply get undefined. This is not magic, but simply syntactic sugar that makes code cleaner and safer.

\n\n

Basic Syntax

\n

The syntax is extremely simple. Instead of writing:

\n
if (user && user.profile && user.profile.name) {\n    console.log(user.profile.name);\n}
\n

You write:

\n
console.log(user?.profile?.name);
\n

If user is undefined, the entire chain is interrupted, and undefined is printed to the console. No errors, no extra checks. Beautiful!

\n\n

How It Works Under the Hood: TypeScript Compilation to JavaScript

\n

TypeScript is a superset of JavaScript. It doesn't execute code directly but compiles it into regular JS. So let's see what our elegant user?.profile?.name turns into after compilation.

\n\n

Example: Simple Optional Chaining

\n

Original TypeScript code:

\n
const name = user?.profile?.name;
\n

After compilation (targeting ES5):

\n
var name = user === null || user === void 0 ? void 0 : user.profile === null || user.profile === void 0 ? void 0 : user.profile.name;
\n

What's happening here? The compiler generates a ternary operator that checks each nesting level for null or undefined. If the value is null or undefined, it returns void 0 (this is just a reliable way to get undefined on older engines). If not, it proceeds. Essentially, this is the same "manual" code we used to write, but now it's generated by the machine.

\n\n

Example: Optional Chaining with Function Calls

\n

The ?. operator works not only with properties but also with function calls. Suppose we have a method getAddress that might be missing:

\n
const address = user?.getAddress?.();
\n

After compilation:

\n
var address = user === null || user === void 0 ? void 0 : (typeof user.getAddress === "function" ? user.getAddress() : void 0);
\n

Notice: the compiler doesn't just check for null, but also verifies that getAddress is a function before calling it. If it's not a function, it returns undef

Blogs

Book Recommendations