Last updated: Feb 29, 2024
Reading timeยท8 min
If you got the error "Argument of type string | undefined is not assignable to parameter of type string", click on the second subheading.
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.
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;
The name
property is marked as
optional
in the Employee
interface.
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
.
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
.One way to solve the error is to use the non-null assertion operator.
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
The exclamation mark is the non-null assertion operator in TypeScript.
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
.
An alternative and much better approach is to use a type guard.
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"
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.
name
variable will always get assigned a string, even if emp.name
is undefined
.You could also use the nullish coalescing operator (??) to solve the error.
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"
null
or undefined
.So, if emp.name
is null
or undefined
, we set the name
variable to an
empty string.
You can also use the logical OR (||) operator in a similar way.
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"
The logical OR (||) operator returns the value to the right if the value to the left is falsy.
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).
if
statement to solve the errorEven a simple if
statement that serves as a type guard can be used to solve
the error.
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"
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.
If nothing of the above works, you can use a type assertion.
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"
We effectively tell TypeScript that emp.name
will be a string
and not to
worry about it.
You can also solve the error by using the Required
utility type to mark all
properties of the object as required.
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);
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.
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.
Here is an example of how the error occurs.
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
.
undefined
which is not compatible with the type of the function's parameter that has to be a string
.One way to get around this is to use a non-null assertion.
function getMessage(message: string) { return message; } // ๐๏ธ const message: "Greetings" | undefined const message = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(message!); // ๐๏ธ non-null assertion
The exclamation mark is the non-null assertion operator in TypeScript.
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
.
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.
function getMessage(message: string) { return message; } // ๐๏ธ const message: "Greetings" | undefined const message = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(message as string); // ๐๏ธ type assertion
We effectively tell TypeScript that the message
variable stores a string and
not to worry about it.
An alternative and much better approach is to use a type guard.
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.
message
variable will always get assigned a string, even if the maybeMessage
variable is undefined
.You could also use the nullish coalescing operator (??) to solve the error.
function getMessage(message: string) { return message; } // ๐๏ธ const message: "Greetings" | undefined const maybeMessage = Math.random() > 0.5 ? 'Greetings' : undefined; getMessage(maybeMessage ?? ''); // ๐๏ธ nullish coalescing
undefined
or null
.If the maybeMessage
variable is undefined
or null
, we pass an empty string
argument to the function.
You can also use the logical OR (||) operator in a similar way.
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.
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).
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.
// ๐๏ธ 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 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.
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.
You can learn more about the related topics by checking out the following tutorials: