Introduction: why is TypeScript yelling at nothing?
\n\nYou're writing code in TypeScript, everything looks logical, but suddenly the compiler outputs: "error TS2533: Object is possibly 'null' or 'undefined'". Sound familiar? This error is one of the most common "pitfalls" for beginners. According to Stack Overflow, the question about suppressing it has garnered over 100,000 views and become a classic.
\n\nBut let's look deeper. TypeScript is not just "strict JavaScript". Its type system, especially the strictNullChecks mode, forces you to explicitly handle cases where a value could be null or undefined. And this is not a bug, but a feature. Error TS2533 is protection against runtime bugs that in JavaScript often lead to Cannot read property of null.
In this article, we'll cover:
\n- \n
- What strictNullChecks is and how it works "under the hood" \n
- Why error TS2533 occurs \n
- 5 ways to suppress it (from simple to advanced) \n
- When each method is appropriate, and when it is not \n
Let's figure out the TypeScript null error once and for all!
\n\nHow strictNullChecks works under the hood
\n\nBy default in TypeScript (starting from version 2.0), the strictNullChecks option is enabled. What does this mean? Previously, null and undefined were considered subtypes of any type. That is, you could assign null to a variable of type string — and TypeScript would stay silent. This simplified code but led to bugs.
In strictNullChecks mode, the types null and undefined are separate entities. A variable of type string can only contain a string. If you want to allow null, you need to explicitly specify string | null.
Example: what the error looks like
\n\n// Example 1: classic error TS2533\ninterface User {\n name: string;\n email?: string; // optional — can be undefined\n}\n\nfunction getUserEmail(user: User): string {\n // Error TS2533: Object is possibly 'undefined'\n return user.email.toUpperCase(); \n}\n\n// Example 2: working with the DOM\nconst button = document.querySelector('button');\n// Error TS2533: Object is possibly 'null'\nbutton.addEventListener('click', () => console.log('clicked'));\n\n\nIn the second example, document.querySelector can return null if the element is not found. TypeScript warns: "Hey, are you sure the button exists?"
5 ways to suppress error TS2533
\n\nNow let's move on to the most important part — how to remove the error. Below are 5 proven methods, from simple to advanced. Choose based on the situation.
\n\n1. Non-null assertion operator (!)
\n\nThe fastest way is to put an exclamation mark ! after the expression. This tells TypeScript: "I know this is not null, trust me."
// Using ! to suppress\nconst button = document.querySelector('button')!;\nbutton.addEventListener('click', () => console.log('clicked'));\n\n// For optional property\nfunction getUserEmail(user: User): string {\n return user.email!.toUpperCase();\n}\n\n\nWhen to use: when you are absolutely sure the value is not null. For example, if you just checked for the element's existence in the DOM. But be careful: if you're wrong — you'll get a runtime error.
\n\n2. Optional chaining (?.) and nullish coalescing (??)
\n\nA modern and safe way. The ?. operator allows you to access a property only if the object is not null/undefined. And ?? sets a default value.
function getUserEmail(user: User): string {\n // If email is undefined — return an empty string\n return user.email?.toUpperCase() ?? '';\n}\n\n// Working with the DOM\ndocument.querySelector('butt