Type 'number or undefined' is not assignable to type number

avatar

Borislav Hadzhiev

Last updated: Mar 6, 2022

banner

Photo from Unsplash

Type 'number or undefined' is not assignable to type number #

The "Type 'number | undefined' is not assignable to type number" error occurs when a possibly undefined value is assigned to something that expects a number. To solve the error, use the non-null assertion operator or a type guard to verify the value is a number before the assignment.

Here is an example of how the error occurs.

index.ts
interface Employee { id: number; name: string; salary?: number; // 👈️ optional } const emp: Employee = { id: 1, name: 'James', salary: 100, }; // ⛔️ Error: Type 'number | undefined' is // not assignable to type 'number'. // Type 'undefined' is not assignable to type 'number'.ts(2322) const salary: number = emp.salary;

The salary property is marked as optional in the Employee interface.

This means that the property can store a number or an undefined value.

The salary variable is typed as a number, so it only expects to get assigned a value that is a number.

TypeScript is basically telling us that the emp.salary property might have a value of undefined, which is not compatible with the type of the salary variable, which only expects a number.

Here are a couple of examples of how you can solve the error.

index.ts
interface Employee { id: number; name: string; salary?: number; } const emp: Employee = { id: 1, name: 'James', salary: 100, }; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const salary: number = emp.salary!; // 👈️ non-null assertion console.log(salary); // 👉️ 100

The exclamation mark is the non-null assertion operator in TypeScript.

It removes null and undefined from a type without doing any explicit type checking.

When you use this approach, you basically tell TypeScript that this value will never be null or undefined.

This approach is very similar to using a type assertion.

index.ts
interface Employee { id: number; name: string; salary?: number; } const emp: Employee = { id: 1, name: 'James', salary: 100, }; const salary: number = emp.salary as number; console.log(salary); // 👉️ 100

Type assertions are used when we have information about the type of a value that TypeScript can't know about.

We effectively tell TypeScript that emp.salary will be a number and not to worry about it.

You could set the type of the salary variable to be number | undefined, which could solve the error depending on your use case.

index.ts
interface Employee { id: number; name: string; salary?: number; } const emp: Employee = { id: 1, name: 'James', salary: 100, }; // 👇️ types now match const salary: number | undefined = emp.salary; console.log(salary); // 👉️ 100

The type of the salary variable now matches the type of the emp.salary property, so no error is shown.

An alternative approach is to use a type guard.

index.ts
interface Employee { id: number; name: string; salary?: number; } const emp: Employee = { id: 1, name: 'James', salary: 100, }; const salary: number = emp.salary !== undefined ? emp.salary : 0; console.log(salary); // 👉️ 100

We used a ternary operator to check if the salary property is not equal to undefined.

If the property is not equal to undefined, it gets assigned to the salary variable, otherwise we use the number 0 as a fallback.

This way we can be sure that the salary variable will always get assigned a number, even if emp.salary is undefined.

You could also use the nullish coalescing operator (??) to solve the error.

index.ts
interface Employee { id: number; name: string; salary?: number; } const emp: Employee = { id: 1, name: 'James', salary: 100, }; const salary: number = emp.salary ?? 0; console.log(salary); // 👉️ 100

The nullish coalescing operator (??) enables us to specify a fallback for when a value is null or undefined.

So, if emp.salary is null or undefined, we set the salary variable to 0.

You can also use the logical OR (||) operator in a similar way.

index.ts
interface Employee { id: number; name: string; salary?: number; } const emp: Employee = { id: 1, name: 'James', salary: 100, }; const salary: number = emp.salary || 0; console.log(salary); // 👉️ 100

The logical OR (||) operator returns the value to the right if the value to the left is falsy.

This is different than the nullish coalescing operator (??) because nullish coalescing only checks for null and undefined.

The logical OR (||) operator would return the value to the right if the value to the left is any of the following: null, undefined, false, 0, "" (empty string), NaN (not a number).

Even a simple if statement that serves as a type guard can be used to solve the error.

index.ts
interface Employee { id: number; name: string; salary?: number; } const emp: Employee = { id: 1, name: 'James', salary: 100, }; let salary = 0; // 👇️ emp.salary is number or undefined here if (emp.salary !== undefined) { // 👇️ emp.salary is number here salary = emp.salary; } console.log(salary); // 👉️ 100

We used the let keyword to initialize the salary variable to 0.

In the if statement, we check if the emp.salary property is not equal to undefined and assign the salary variable to the corresponding value.

Conclusion #

The "Type 'number | undefined' is not assignable to type number" error occurs when a possibly undefined value is assigned to something that expects a number. To solve the error, use the non-null assertion operator or a type guard to verify the value is a number before the assignment.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.