NonNullable<Type> Utility Types in TypeScript With Examples
What Is NonNullable<Type>
NonNullable<Type> is a utility type in TypeScript that helps you create a new
type by removing null and undefined from an existing type. Essentially
NonNullable<Type> makes sure that the values assigned to the new type cannot
be null or
undefined. This helps you write safer code, ensuring that you won't encounter
unexpected errors caused by these values.
Syntax
Here's the basic syntax for using NonNullable<Type>
type NewType = NonNullable<Type>;
NonNullable: This is the name of the utility type. It indicates that you want to create a non-nullable version of an existing type.<Type>: The angle brackets<and>are used to specify a type parameter. You replaceTypewith the actual type you want to make non-nullable.
For example, let's say you have a type called MyType which can be either a
string, number, null, or undefined:
type MyType = string | number | null | undefined;
Now, you want to create a new type that removes the null and undefined
possibilities. You would use the NonNullable utility type like this:
type MyNonNullType = NonNullable<MyType>;
After applying NonNullable, the new type MyNonNullType will only
accept string
and number values. It will not allow null or undefined values.


Time To Transition From JavaScript To TypeScript
Level Up Your TypeScript And Object Oriented Programming Skills. The only complete TypeScript course on the marketplace you building TypeScript apps like a PRO.
SEE COURSE DETAILSExample Use Case
Imagine you're developing an eCommerce application, and you have a Product
type representing a product in your store. The product can have a discount,
which can be either a fixed amount or a percentage. The discount can also be
null if there is no discount available.
type Discount = {
type: "fixed" | "percentage" | null;
value: number | null;
};
type Product = {
id: string;
name: string;
price: number;
discount: Discount;
};
Now, let's say you need to create a function that calculates the discounted
price of a product, but it should only accept products that have valid
discounts. You can use NonNullable<Type> to make sure that the discount type
and
value are not null.
First, create a new ValidDiscount type that removes the null possibility
from
the discount type and value:
type ValidDiscount = {
type: NonNullable<Discount["type"]>;
value: NonNullable<Discount["value"]>;
};
Next, create a new ProductWithDiscount type, which is the same as the original
Product type, but with the ValidDiscount type for the discount property:
type ProductWithDiscount = Omit<Product, "discount"> & {
discount: ValidDiscount;
};
Finally, define the calculateDiscountedPrice function, which accepts
a ProductWithDiscount as an argument:
function calculateDiscountedPrice(product: ProductWithDiscount): number {
const { price, discount } = product;
if (discount.type === "fixed") {
return price - discount.value;
} else if (discount.type === "percentage") {
return price * (1 - discount.value / 100);
}
// This point should never be reached,
// as the discount is guaranteed to be valid.
return price;
}
By using NonNullable<Type>, you ensure that the calculateDiscountedPrice
function only accepts products with valid discounts, avoiding errors caused by
null values in the discount type or value.
Combining NonNullable<Type> With Other Utility Types
Let's try to combine NonNullable<Type> with the Partial<Type> utility type.
Let's consider a User type representing a user profile in a social media
application:
type User = {
id: string;
name: string;
email: string;
bio: string | null;
birthDate: Date | null;
};
Now, imagine you want to create a function to update a user's profile, allowing
the user to update only some of the fields (name, email, bio,
and birthDate).
You also want to make sure that after the update, the name and email fields
are
not null. You can use Partial<Type> and NonNullable<Type> together to
achieve
this.
First, create a UserUpdate type using Partial<Type> to make all properties
optional:
type UserUpdate = Partial<User>;
Next, update the name and email properties to be non-nullable by
combining NonNullable<Type> with the mapped type:
type NonNullableUserUpdate = {
[K in keyof UserUpdate]: K extends "name" | "email"
? NonNullable<UserUpdate[K]>
: UserUpdate[K];
};
Now, you can define the updateUserProfile function, which accepts a userId
and a
NonNullableUserUpdate object, and updates the user's profile accordingly:
function updateUserProfile(
userId: string,
update: NonNullableUserUpdate
): User {
// Fetch the user from the database
// (assuming a `getUserById` function exists)
const user = getUserById(userId);
// Update the user's properties
for (const key in update) {
user[key] = update[key];
}
// Save the updated user back to the
// database (assuming a `saveUser` function exists)
saveUser(user);
return user;
}
By combining NonNullable<Type> with other utility types, you can create more
advanced and flexible types, while ensuring type safety and avoiding potential
errors caused by null or undefined values.
What Can You Do Next 🙏😊
If you liked the article, consider subscribing to Cloudaffle, my YouTube Channel, where I keep posting in-depth tutorials and all edutainment stuff for software developers.