TypeScript compiler errors can be big and scary, and a good skill to have in your back pocket when errors do happen is being able to interpret the key information in the error to help you understand the problem and iterate over solutions. Let's take a look at two errors that might be hard to understand and catch you off guard.
1No overload matches this call.2 Overload 1 of 2, '(options: B): Promise<void>', gave the following error.3 Argument of type 'A | B' is not assignable to parameter of type 'B'.4 Type 'A' is not assignable to type 'B'.5 Type 'A' is not assignable to type '{ async: true; }'.6 Types of property 'async' are incompatible.7 Type 'false | undefined' is not assignable to type 'true'.8 Type 'undefined' is not assignable to type 'true'.9 Overload 2 of 2, '(options: A): void', gave the following error.10 Argument of type 'A | B' is not assignable to parameter of type 'A'.11 Type 'B' is not assignable to type 'A'.12 Types of property 'async' are incompatible.13 Type 'true' is not assignable to type 'false | undefined'.
Whew boy, that's a big one. There's a lot of information here, so let's unpack this. First step when reading any error is filtering out unneeded information, and looking at keywords to extract from the message: "No overload matches this call". Under the error message, there's two overloads that are reporting errors:
1Overload x of y, '(arguments): return type', gave the following error.
With each line of indentation, the error goes more and more into detail about what caused the error for each overload.
What exactly is an overload, and why does it matter that "no overloads match this call"?
An overload is essentially an alternative set of arguments and return type that a function can have depending on what is passed in. Let's take a simple add
function:
1function add(a: number, b: number): number {2 return a + b;3}
Let's say we wanted to add an "assertion mode" to this add
function, which will return true
or false
depending on if a third number we pass in (c
) equals the result of a + b
1function add(a: number, b: number): number;2function add(a: number, b: number, c: number): boolean;3function add(a: number, b: number, c?: number) {4 if (c) return a + b === c5 return a + b6}
The add
function now has two overloads. It can be confusing, but the first two lines are
a
, b
and c
must all be numbers and add
must return a boolean.The compiler will match a specific overload, provided the call to the function is provided with arguments where the types match at least one of the overloads above.
If add
is called with two arguments, the first overload is matched:
If add
is called with three arguments, the second overload is matched:
In Visual Studio Code, you can see the overloads a function has on the left of the tooltip. Overloads aren't widely used in TypeScript anymore, many preferring to use
.Since we have an error complaining about "no overloads matching this call", we know it's related to arguments being passed into a function with multiple overloads, potentially with the wrong type. If you're seeing this error, it's best to double check that you're passing the right arguments with the right types into the function for the overload you want to target.
type
are incompatible1Argument of type '{ type: string };' is not assignable to parameter of type 'Schema'23Type '{ type: string; }' is not assignable to type 'Schema'45Types of property 'type' are incompatible.67Type 'string' is not assignable to type '"string" | "number"'
Usually when you see this error, you'll also see "type x
is not assignable to type y
". What does it mean for a type to be "not assignable" to another type?
TypeScript's own documentation
means, and says a type is considered assignable to another type if "one is an acceptable substitute for another" - basically, both types need to have the same "shape" or structure. You can't assign anumber
to a string
, and you can't assign { a: number }
to { a: string }
. In both examples, you couldn't substitute the first type for the second or vice versa.You might encounter this error if an object you're supplying to an argument for a function does not make a suitable substitute for the type the function is requesting for that argument (like the two objects in the example before). Double check that every property in the object you're supplying matches the type definition for the function you're using.
string
typeOne thing to be wary of if you get this error is the fact that the type string
is not assignable to one particular string literal, such as "test"
. In this cases, you might find yourself with an error like, Type 'string' is not assignable to type '"test"'
.
1const getType = () => "string";2const type = getType();34type TestType = { type: "string" | "number" };5// Type 'string' is not assignable to type '"string" | "number"'6const obj: TestType = { type }; // ❌ type: string
A "string literal"
is a different type to string
(note the quote marks!) and it makes sense that the literal string "test"
is not a substitute for all strings (string
). However, any string literal like "test"
is assignable to string
.
A quick fix for this problem (for TypeScript 3.4+) is to add as const
to the end of your string so that the content of the string is the type.
1const getType = () => "string" as const;2const type = getType();34type TestType = { type: "string" | "number" };5const obj: TestType = { type }; // ✅ type: 'string'
Something also worth mentioning is the difference between defining strings using var
or let
compared to const
. When defining a string using var
or let
, the compiler will infer the type as string
automatically. When defining a string using const
,
1let changingString = "Hello World";2// type is `string`: since variables defined with3// `let` are mutable, this *could* represent other4// values56const constantString = "Hello World";7// type is `"Hello World"`: this is a constant8// variable and can only represent one value910// using a method to change the string11// like `.reverse()` will simply change12// the type to a `string`
The TypeScript documentation has a good
, and there's a lot more you can do if the error you're facing is really stubborn. Try to strip unnecessary parts of code to get to the heart of the problem, or if all else fails, look into creating a (there's a good guide by ) to see if you can reproduce the problem from scratch, and divide and conquer to find out if there's something wrong with your code, or potentially a dependency you use.Subscribe to the Nevuletter so you never miss new posts.
Comments
• 0
You need to be signed in to comment