Understanding Nullish, Non-Nullish, and Asserting Non-Nullish Values in TypeScript

Comprehensive guide to handling null & undefined values in TypeScript, leveraging AssertNonNullish & Nullish Coalescing for type safety

Irene Smolchenko
JavaScript in Plain English

--

Illustration of the nullish variables concept, represented by a clear round marble resting on a brown rock.
Photo by Marc Schulte on Unsplash

In TypeScript, the concepts of nullish, non-nullish, and assertNonNullish are related to handling null and undefined values. These concepts help you write more reliable and type-safe code by providing explicit ways to handle nullable values.

By the end of this post, you’ll have a clear understanding of these concepts and discover explicit techniques to handle nullable values effectively.

Nullish

In TypeScript, the term “nullish” refers to values that are null or undefined. These values represent the absence of a value.
By default, variables are nullable (meaning they can hold these nullish values), unless you explicitly specify them as non-nullable using the type annotations or the strictNullChecks compiler option.

The strictNullChecks compiler option enforces strict null checks, which means you’ll receive compile-time errors if you attempt to assign a null or undefined value to a variable that is explicitly marked as non-nullable.

To enable strick null checks, either pass the --strictNullChecks flag when invoking the TypeScript compiler via the command line:
tsc --strictNullChecks yourfile.ts

Or configure directly in the tsconfig file:

{
"compilerOptions": {
"strictNullChecks": true
}
}

Non-Nullish

The term “non-nullish” is the opposite of “nullish.” It refers to values that are not null or undefined— in other words, values that exist and have a defined state.

When a variable is declared with a non-nullish type (when you specify a type for a variable that is not nullable), TypeScript guarantees that it will never be assigned a null or undefined value.

Here’s an example where non-nullish checking can be useful:

function greetUser(name?: string): void {
const userName = name ?? "Guest";
console.log(`Hello, ${userName}!`);
}

greetUser(); // Output: Hello, Guest!
greetUser("John"); // Output: Hello, John!

In this example, we have a greetUser function that takes an optional name parameter (using the ? symbol) , which represents the name of the user to greet. Inside the function, we use the nullish coalescing operator (??) to check if the name parameter is nullish.

The nullish coalescing operator returns the right-hand value of the expression if the left-hand value is null or undefined. In all other falsy cases, such as 0, empty strings, or false, the value of the variable is returned instead of the default value.

Here, the userName variable will always have a non-nullish value. By using ??, we provide a fallback value (“Guest”) when the name parameter is nullish, ensuring a proper greeting message is displayed. This prevents any potential issues or errors that may occur if we directly use a nullish value.

AssertNonNullish

The assertNonNullish is not a built-in TypeScript construct, but rather a concept that represents a technique to ensure that a value is non-nullish. It’s a way to inform the TypeScript compiler that a variable will have a non-nullish value at a certain point in the code, even if its type suggests otherwise.

One common way to assert non-nullishness is by using the ! (exclamation mark) operator, also known as the non-null assertion operator. When you append ! to a variable or property, you’re essentially telling TypeScript that you know better than the compiler (a way to override the strictNullChecks temporarily) and that the value will not be null or undefined at that specific point in the code.

Here’s a real-world example where the non-null assertion (!) operator can be useful:

interface User {
id: number;
name: string;
email: string | null;
}

function sendEmailToUser(user: User): void {
// Ensure user email is non-null before sending email
const userEmail = user.email!;

if (userEmail !== null) {
// Sending email logic...
console.log(`Sending email to ${user.name} at ${userEmail}`);
} else {
// Handle the case where the email address is missing
console.log(`Cannot send email to ${user.name}. Email address is missing.`);
}
}

const userWithValidEmail: User = {
id: 1,
name: "John Doe",
email: "john.doe@example.com",
};

const userWithMissingEmail: User = {
id: 2,
name: "Jane Smith",
email: null,
};

sendEmailToUser(userWithValidEmail); // Sending email to John Doe at john.doe@example.com
sendEmailToUser(userWithMissingEmail); // Cannot send email to Jane Smith. Email address is missing.

Be sure to use the ! operator with caution and only when you are absolutely sure that the value will not be null or undefined. Incorrect usage may lead to runtime errors if the assertion is incorrect.

In the example above, by using the non-null assertion, we inform the TypeScript compiler that we are confident that user.email won’t be null at that specific point in the code. However, it’s still important to perform proper null checks to handle unexpected null values gracefully, as demonstrated.

Recap

The concepts of nullish, non-nullish, and assertNonNullish are inherent to TypeScript and can be used without any additional configuration. Enabling strictNullChecks is recommended for catching null and undefined errors during compilation.

We discussed the technique of assertNonNullish using the ! operator, which helps bypass strict null checks in specific situations. Additionally, we explored the nullish coalescing operator (??), which allows for seamless fallback to default values in expressions, making your code easier to understand and more dependable.

I hope you found this post useful. ✨
Stay tuned for future content! If you’re new here, feel free to explore my other articles, and consider following me for future updates and more valuable insights.

By buying me a virtual croissant on Buy Me a Coffee, you can directly support my creative journey. Your contribution helps me continue creating high-quality content. Thank you for your support!

More content at PlainEnglish.io.

Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.

--

--

🍴🛌🏻 👩🏻‍💻 🔁 Front End Web Developer | Troubleshooter | In-depth Tech Writer | 🦉📚 Duolingo Streak Master | ⚛️ React | 🗣️🤝 Interviews Prep