Argument type 'unknown' is not assignable parameter of type

avatar

Borislav Hadzhiev

Last updated: Mar 23, 2022

banner

Photo from Unsplash

Argument type 'unknown' is not assignable parameter of type #

The error "Argument of type 'unknown' is not assignable to parameter of type" occurs when we try to pass an argument of type unknown to a function that expects a different type. To solve the error, use a type assertion or a type guard when calling the function.

argument type unknown not assignable parameter

Here is an example of how the error occurs.

index.ts
function getMessage(message: string) { return message; } const message: unknown = 'Hello world'; // ⛔️ Error: Argument of type 'unknown' is not assignable // to parameter of type 'string'.ts(2345) getMessage(message);

The message variable has a type of unknown.

This often happens when fetching data from a remote API because TypeScript doesn't know the shape of the values we're working with.

The unknown type is the type-safe counterpart of any.

If you are certain that the specific value has a compatible type, but TypeScript doesn't know about it, use a type assertion, e.g. value as RightType when calling the function.

index.ts
function getMessage(message: string) { return message; } const message: unknown = 'Hello world'; getMessage(message as string); // 👈️ type assertion

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

If you don't know the type of the function parameter and just want to turn off type checking, use the any type.

index.ts
function getMessage(message: string) { return message; } const message: unknown = 'Hello world'; getMessage(message as any); // 👈️ type assertion

The any type effectively turns off type checking, so we wouldn't get a type error, but we also don't take advantage of TypeScript.

An alternative solution is to use a type guard.

index.ts
function getMessage(message: string) { return message; } const message: unknown = 'Hello world'; if (typeof message === 'string') { const result = getMessage(message); console.log(result); // 👉️ "Hello world" }

We explicitly check if the message variable stores a value of type string before calling the function.

TypeScript knows that once we're in the if block, the message variable is guaranteed to be a string.

When working with the unknown type, we basically tell TypeScript - we're going to get this value, but we don't know its type. We are just going to check with a couple of if statements to track it down and use it safely. In the if blocks, give us support for the particular type that is checked for.

Here is an example of how you would use a type guard when working with objects.

index.ts
interface Employee { id: number; name: string; salary: number; } // 👇️ Check if passed in object has properties of Employee function isAnEmployee(obj: any): obj is Employee { return ( typeof obj === 'object' && obj !== null && 'id' in obj && 'name' in obj && 'salary' in obj ); } const obj: unknown = { id: 1, name: 'Alice', salary: 500, }; function getEmployee(emp: Employee) { return emp; } if (isAnEmployee(obj)) { // 👉️ obj is type Employee here const result = getEmployee(obj); console.log(result); // 👉️ {id: 1, name: 'James', salary: 100} }

We used a user-defined type guard to check if an object has all of the properties of the Employee type.

The obj is Employee syntax is a type predicate where obj must be the name of the parameter the function takes.

If the isAnEmployee function returns true, TypeScript knows that the passed in value is of type Employee and allows us to pass the object as an argument to the function.

The example above simply checks if the passed-in value is an object and contains the id, name and salary properties.

The goal is to make sure that the type of the argument we are passing to the function is compatible with the type of the function's parameter.

Here is an example of how to use a type guard to check if a value of type unknown is an array.

index.ts
type Employee = { id: number; name: string; salary: number; }; const emps: unknown = [ { id: 1, name: 'Alice', salary: 100 }, { id: 2, name: 'Bob', salary: 200 }, { id: 3, name: 'Carl', salary: 300 }, ]; function getEmployees(emps: Employee[]) { return emps; } if (Array.isArray(emps)) { getEmployees(emps as Employee[]); }

We used the Array.isArray() method to check if the emps variable stores an array before the assignment.

You might have to be more strict and check if the array has any elements and whether they contain specific properties, etc.

Conclusion #

To solve the "Argument of type 'unknown' is not assignable to parameter of type" TypeScript error, use a type assertion or a type guard to verify that the argument is of the expected type. The error is caused when a value of type unknown is passed to a function.

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.