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

avatar
Borislav Hadzhiev

Last updated: Feb 29, 2024
8 min

banner

# Table of Contents

  1. Type 'string or undefined' is not assignable to type string
  2. Argument of type 'string or undefined' is not assignable to parameter of type string

If you got the error "Argument of type string | undefined is not assignable to parameter of type string", click on the second subheading.

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

The "Type 'string | undefined' is not assignable to type string" error occurs when a possibly undefined value is assigned to something that expects a string.

To solve the error, use the non-null assertion operator or a type guard to verify the value is a string before the assignment.

Here is an example of how the error occurs.

index.ts
interface Employee { id: number; name?: string; // ๐Ÿ‘ˆ๏ธ optional (might be undefined) salary: number; } const emp: Employee = { id: 1, name: 'Bobby Hadz', salary: 100, }; // โ›”๏ธ Error: Type 'string | undefined' is not assignable to type 'string'. // Type 'undefined' is not assignable to type 'string'.ts(2322) const name: string = emp.name;

type undefined is not assignable to type string

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

Therefore the property can store a string or an undefined value.

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

TypeScript is telling us that the emp.name property might have a value of undefined which is not compatible with the type of the name variable which only expects a string.

# Use the non-null assertion operator to solve the error

One way to solve the error is to use the non-null assertion operator.

index.ts
interface Employee { id: number; name?: string; salary?: number; } const emp: Employee = { id: 1, name: 'Bobby Hadz', salary: 100, }; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const name: string = emp.name!; // ๐Ÿ‘ˆ๏ธ non-null assertion

use non null assertion operator to solve the error

The code for this article is available on GitHub

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.

# Use a type-guard to solve the error

An alternative and much better approach is to use a type guard.

index.ts
interface Employee { id: number; name?: string; salary?: number; } const emp: Employee = { id: 1, name: 'Bobby Hadz', salary: 100, }; const name: string = emp.name !== undefined ? emp.name : ''; console.log(name); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

use type guard to solve the error

The code for this article is available on GitHub

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

If the property is not equal to undefined, it gets assigned to the name variable, otherwise, we use an empty string as a fallback.

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

# Use the nullish coalescing operator (??) to solve the error

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: 'Bobby Hadz', salary: 100, }; const name: string = emp.name ?? ''; console.log(name); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

use nullish coalescing operator to solve the error

The code for this article is available on GitHub
The nullish coalescing operator (??) enables us to specify a fallback for when a value is null or undefined.

So, if emp.name is null or undefined, we set the name variable to an empty string.

# Use the logical OR (||) operator to solve the error

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: 'Bobby Hadz', salary: 100, }; const name: string = emp.name || ''; console.log(name); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

use logical or operator to solve the error

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

This is different from 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).

# Use an if statement to solve the error

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: 'Bobby Hadz', salary: 100, }; let name = ''; // ๐Ÿ‘‡๏ธ emp.name is a string or undefined here if (emp.name !== undefined) { // ๐Ÿ‘‡๏ธ emp.name is string here name = emp.name; } console.log(name); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

use if statement to solve the error

The code for this article is available on GitHub

We used the let keyword to initialize the name variable to an empty string.

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

# Use a type assertion to solve the error

If nothing of the above works, you can use a type assertion.

index.ts
interface Employee { id: number; name?: string; salary?: number; } const emp: Employee = { id: 1, name: 'Bobby Hadz', salary: 100, }; const name: string = emp.name as string; // ๐Ÿ‘ˆ๏ธ type assertion console.log(name); // ๐Ÿ‘‰๏ธ "Bobby Hadz"

use type assertion to solve the error

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.name will be a string and not to worry about it.

# Using the Required utility type to solve the error

You can also solve the error by using the Required utility type to mark all properties of the object as required.

index.ts
interface Employee { id: number; name?: string; // ๐Ÿ‘ˆ๏ธ optional (might be undefined) salary: number; } const emp: Required<Employee> = { id: 1, name: 'Bobby Hadz', salary: 100, }; const name: string = emp.name; console.log(name);
The code for this article is available on GitHub

We used the Required utility type to construct a new type with all of the properties of the provided type set to required.

The name property is no longer optional in the new type, so it can never store an undefined value.

# Argument of type 'string or undefined' is not assignable to parameter of type string

The error "Argument of type string | undefined is not assignable to parameter of type string" occurs when a possibly undefined value is passed to a function that expects a string.

To solve the error, use a type guard to verify the value is a string before passing it to the function.

argument of type undefined is not assignable to parameter of type string

Here is an example of how the error occurs.

index.ts
function getMessage(message: string) { return message; } // ๐Ÿ‘‡๏ธ const message: "Greetings" | undefined const message = Math.random() > 0.5 ? 'Greetings' : undefined; // โ›”๏ธ Error: Argument of type 'string | undefined' is not // assignable to parameter of type 'string'. // Type 'undefined' is not assignable to type 'string'. ts(2345) getMessage(message);

The function expects to be called with an argument of type string but the passed in argument is possibly undefined.

TypeScript is telling us that the value we are passing to the function might be undefined which is not compatible with the type of the function's parameter that has to be a string.

# Use a non-null assertion in the function call

One way to get around this is to use a non-null assertion.

index.ts
function getMessage(message: string) { return message; } // ๐Ÿ‘‡๏ธ const message: "Greetings" | undefined const message = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(message!); // ๐Ÿ‘ˆ๏ธ non-null assertion
The code for this article is available on GitHub

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

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

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

# Use a type assertion in the function call

This is very similar to a type assertion and should only be used when you're absolutely sure that the value is of the expected type.

index.ts
function getMessage(message: string) { return message; } // ๐Ÿ‘‡๏ธ const message: "Greetings" | undefined const message = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(message as string); // ๐Ÿ‘ˆ๏ธ type assertion
The code for this article is available on GitHub
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 the message variable stores a string and not to worry about it.

# Use the ternary operator to solve the error

An alternative and much better approach is to use a type guard.

index.ts
function getMessage(message: string) { return message; } // ๐Ÿ‘‡๏ธ const message: "Greetings" | undefined const maybeMessage = Math.random() > 0.5 ? 'Greetings' : undefined; const message: string = maybeMessage !== undefined ? maybeMessage : ''; getMessage(message);

We used the ternary operator to check if the maybeMessage variable is not equal to undefined.

If it's not equal to undefined, it gets assigned to the message variable, otherwise, we use an empty string as a fallback.

This way we can be sure that the message variable will always get assigned a string, even if the maybeMessage variable is undefined.

# Use the nullish coalescing operator (??) in the function call

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

index.ts
function getMessage(message: string) { return message; } // ๐Ÿ‘‡๏ธ const message: "Greetings" | undefined const maybeMessage = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(maybeMessage ?? ''); // ๐Ÿ‘ˆ๏ธ nullish coalescing
The code for this article is available on GitHub
The nullish coalescing operator (??) enables us to specify a fallback for when a value is undefined or null.

If the maybeMessage variable is undefined or null, we pass an empty string argument to the function.

# Use the logical OR (||) operator in the function call

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

index.ts
function getMessage(message: string) { return message; } // ๐Ÿ‘‡๏ธ const message: "Greetings" | undefined const maybeMessage = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(maybeMessage || '');

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

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

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).

# Update the type of the function's parameter

The cause of the error is that the type of the function's parameter and the type of the passed-in argument are not compatible.

Depending on your use case, you could also solve the error by updating the type of the function's parameter and making the parameter and the passed-in argument compatible types.

index.ts
// ๐Ÿ‘‡๏ธ parameter is type string or undefined function getMessage(message: string | undefined) { return message; } // ๐Ÿ‘‡๏ธ argument is also type string or undefined const maybeMessage = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(maybeMessage);
The code for this article is available on GitHub

The function's parameter is now typed as string or undefined, so we are able to pass it an argument of type string or undefined because the two types are compatible.

We used a union type in the example, but we could have also marked the parameter as optional.

index.ts
function getMessage(message?: string) { // ๐Ÿ‘ˆ๏ธ optional return message; } // ๐Ÿ‘‡๏ธ argument is also type string or undefined const maybeMessage = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(maybeMessage);

The code sample achieves the same result. When a parameter is marked as optional, it can either be of the specified type or have an undefined value.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

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.

Copyright ยฉ 2024 Borislav Hadzhiev