Typescript: 3.7.2
vue-property-decorator: 8.3.0
Vue: 2.6.10
All compiles fine, and I see component in browser which is working as expected, BUT
I forced to use ts-ignore on Vue initialization =(
Just uncomment this line,
and start npm run deploy.dev
and you catch this error:
error TS2769: No overload matches this call.
Overload 1 of 3, '(options?: ThisTypedComponentOptionsWithArrayProps<Vue, { mySelected: null; }, object, object, "$el" | "$options" | "$parent" | "$root" | "$children" | "$refs" | "$slots" | "$scopedSlots" | "$isServer" | "$data" | "$props" | ... 15 more ... | "$createElement"> | undefined): CombinedVueInstance<...>', gave the following error.
Argument of type '{ el: string; components: { IamHeader: typeof IamHeader; IamSelect: typeof IamSelect; }; data: { mySelected: null; }; }' is not assignable to parameter of type 'ThisTypedComponentOptionsWithArrayProps<Vue, { mySelected: null; }, object, object, "$el" | "$options" | "$parent" | "$root" | "$children" | "$refs" | "$slots" | "$scopedSlots" | "$isServer" | "$data" | "$props" | ... 15 more ... | "$createElement">'.
Type '{ el: string; components: { IamHeader: typeof IamHeader; IamSelect: typeof IamSelect; }; data: { mySelected: null; }; }' is not assignable to type 'ComponentOptions<Vue, DataDef<{ mySelected: null; }, Record<"$el" | "$options" | "$parent" | "$root" | "$children" | "$refs" | "$slots" | "$scopedSlots" | "$isServer" | "$data" | "$props" | "$ssrContext" | ... 14 more ... | "$createElement", any>, Vue>, object, object, ("$el" | ... 25 more ... | "$createElement")[],...'.
Types of property 'components' are incompatible.
Type '{ IamHeader: typeof IamHeader; IamSelect: typeof IamSelect; }' is not assignable to type '{ [key: string]: VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...>; }'.
Property 'IamHeader' is incompatible with index signature.
Type 'typeof IamHeader' is not assignable to type 'VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...>'.
Type 'typeof IamHeader' is not assignable to type 'VueConstructor<Vue>'.
Type 'IamHeader' is not assignable to type 'CombinedVueInstance<Vue, object, object, object, Record<never, any>>'.
Type 'IamHeader' is missing the following properties from type 'Vue': $el, $options, $parent, $root, and 23 more.
Overload 2 of 3, '(options?: ThisTypedComponentOptionsWithRecordProps<Vue, { mySelected: null; }, object, object, { readonly $el: unknown; readonly $options: unknown; readonly $parent: unknown; readonly $root: unknown; readonly $children: unknown; readonly $refs: unknown; readonly $slots: unknown; ... 19 more ...; $createElement: unknown; }> | undefined): CombinedVueInstance<...>', gave the following error.
Argument of type '{ el: string; components: { IamHeader: typeof IamHeader; IamSelect: typeof IamSelect; }; data: { mySelected: null; }; }' is not assignable to parameter of type 'ThisTypedComponentOptionsWithRecordProps<Vue, { mySelected: null; }, object, object, { readonly $el: unknown; readonly $options: unknown; readonly $parent: unknown; readonly $root: unknown; readonly $children: unknown; readonly $refs: unknown; readonly $slots: unknown; readonly $scopedSlots: unknown; ... 18 more ......'.
Type '{ el: string; components: { IamHeader: typeof IamHeader; IamSelect: typeof IamSelect; }; data: { mySelected: null; }; }' is not assignable to type 'ComponentOptions<Vue, DataDef<{ mySelected: null; }, { readonly $el: unknown; readonly $options: unknown; readonly $parent: unknown; readonly $root: unknown; readonly $children: unknown; readonly $refs: unknown; readonly $slots: unknown; readonly $scopedSlots: unknown; ... 18 more ...; $createElement: unknown; }, Vu...'.
Types of property 'components' are incompatible.
Type '{ IamHeader: typeof IamHeader; IamSelect: typeof IamSelect; }' is not assignable to type '{ [key: string]: VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...>; }'.
Overload 3 of 3, '(options?: ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>> | undefined): CombinedVueInstance<...>', gave the following error.
Argument of type '{ el: string; components: { IamHeader: typeof IamHeader; IamSelect: typeof IamSelect; }; data: { mySelected: null; }; }' is not assignable to parameter of type 'ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>>'.
Types of property 'components' are incompatible.
Type '{ IamHeader: typeof IamHeader; IamSelect: typeof IamSelect; }' is not assignable to type '{ [key: string]: VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...>; }'.
Property 'IamHeader' is incompatible with index signature.
Type 'typeof IamHeader' is not assignable to type 'VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...>'.
Type 'typeof IamHeader' is not assignable to type 'VueConstructor<Vue>'.
TypeScript: 1 semantic error
TypeScript: emit failed
[10:57:17] 'transpile.dev' errored after 1.56 s
[10:57:17] Error: TypeScript: Compilation failed
at Output.mightFinish (C:Projectssystemjs-ts-es6-vuenode_modulesgulp-typescriptreleaseoutput.js:131:43)
at Output.finish (C:Projectssystemjs-ts-es6-vuenode_modulesgulp-typescriptreleaseoutput.js:123:14)
at ProjectCompiler.inputDone (C:Projectssystemjs-ts-es6-vuenode_modulesgulp-typescriptreleasecompiler.js:97:29)
at CompileStream.end (C:Projectssystemjs-ts-es6-vuenode_modulesgulp-typescriptreleaseproject.js:125:31)
at DestroyableTransform.onend (C:Projectssystemjs-ts-es6-vuenode_modulesreadable-streamlib_stream_readable.js:577:10)
at Object.onceWrapper (events.js:286:20)
at DestroyableTransform.emit (events.js:203:15)
at DestroyableTransform.EventEmitter.emit (domain.js:466:23)
at endReadableNT (C:Projectssystemjs-ts-es6-vuenode_modulesreadable-streamlib_stream_readable.js:1010:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Type 'typeof IamHeader' is not assignable to type 'VueConstructor<Vue>
from src
@Component({
name,
template,
})
export class IamHeader extends Mixins(BemComponent) {
}
from src
@Component
export class BemComponent extends Vue
implements IBem, IClassComponent {
}
You use overloading in TypeScript and accidentally get the “No overload matches this call” error. This article will help you answer questions related to that error.
What does “No overload matches this call” error mean?
The reason for the error
The error message: ‘No overload matches this call’ appears when you call a function with arguments that do not match its declared overloaded functions. It could be that the number of parameters is not the same or the data type is different.
Situations where the error occurs
Example 1:
// Overload signatures function favorites(drink: string): string; function favorites(drinks: string[]): string[]; // Implementation signature function favorites(drink: unknown): unknown { if (typeof drink === 'string') { return `I love ${drink}`; } else if (Array.isArray(drink)) { return drink.map(d => `I love ${d}`); } throw new Error('Something went wrong, please try again!'); } const myDrink: unknown = 'Orange Juice'; console.log(favorites(myDrink)); // Error
Output:
error: No overload matches this call.
Overload 1 of 2, '(drink: string): string', gave the following error.
Argument of type 'unknown' is not assignable to parameter of type 'string'.
Overload 2 of 2, '(drinks: string[]): string[]', gave the following error.
Argument of type 'unknown' is not assignable to parameter of type 'string[]'.
In this example, as you can see, even though the implementation function accepts an unknown type for argument, we get an error when we call a function with an argument of unknown type. The reason is that we can not execute the implementation function directly. We have to call one of the overload signatures.
Example 2:
function overloadFunc(x: number, y: number): number function overloadFunc(x: string, y: string): string function overloadFunc(x: any, y: any): any { return x + y; } function overloadFuncDemo(x: string | number, y: number | string) { return overloadFunc(x, y); } console.log(overloadFuncDemo(8, 10))
Output:
No overload matches this call.
Overload 1 of 2, '(x: number, y: number): number', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.
Overload 2 of 2, '(x: string, y: string): string', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'string'.
Type 'number' is not assignable to type 'string'.
The ‘overloadFunc’ function has two overload signatures and one implementation signature in this second example.
The first function takes two parameters of ‘number’ type and returns a number.
The second function takes two parameters of ‘string’ type and returns a string.
We have an error message in the output because the TypeScript compiler doesn’t know what type of parameter you are precisely trying to pass to the function.
Solutions to fix this error
In the case of example 1
The way to eliminate errors is to use the correct argument’s type declared in the overload signatures. The program will be edited as follow:
// Overload signatures function favorites(drink: string): string; function favorites(drinks: string[]): string[]; // Implementation signature function favorites(drink: unknown): unknown { if (typeof drink === 'string') { return `I love ${drink}`; } else if (Array.isArray(drink)) { return drink.map(d => `I love ${drink}`); } throw new Error('Something went wrong, please try again!'); } const myDrink: string = 'Orange Juice'; //use 'string' instead of 'unknown' console.log(favorites(myDrink));
Output:
‘I love Orange Juice’
In the case of example 2
When the data type is not clear, you have to use type assertion by adding ‘as any’ after x and y when you call the overloadFunc()
function in overloadFuncDemo()
function.
function overloadFunc(x: number, y: number): number; function overloadFunc(x: string, y: string): string; function overloadFunc(x: any, y: any): any { return x + y; } function overloadFuncDemo(x: string | number, y: number | string) { return overloadFunc(x as any, y as any); } console.log(overloadFuncDemo(8, 10))
Output:
18
Summary
That’s the whole point of this article. You have gone through a few error cases and their respective fixes to better understand the cause of the “No overload matches this call” error in TypeScript. Thank you for reading!
Maybe you are interested:
- Object is of type ‘unknown’ Error in TypeScript
- object is possibly ‘null’ or ‘undefined’ error in ts
My name’s Christopher Gonzalez. I graduated from HUST two years ago, and my major is IT. So I’m here to assist you in learning programming languages. If you have any questions about Python, JavaScript, TypeScript, Node.js, React.js, let’s contact me. I will back you up.
Name of the university: HUST
Major: IT
Programming Languages: Python, JavaScript, TypeScript, Node.js, React.js
Содержание
- TS2769: No overload matches this call #374
- Comments
- This comment has been minimized.
- This comment has been minimized.
- My mistake which caused this:
- Possible another solution
- Possible another solution
- Ts2769 no overload matches this call the last overload gave the following error
- No overload matches this call error in TypeScript #
- Conclusion #
- error TS2769: No overload matches this call. #2955
- Comments
- Reproduction
- Environment
- System:
- Binaries:
- npmPackages:
TS2769: No overload matches this call #374
Typescript: 3.7.2
vue-property-decorator: 8.3.0
Vue: 2.6.10
All compiles fine, and I see component in browser which is working as expected, BUT
I forced to use ts-ignore on Vue initialization =(
Just uncomment this line,
and start npm run deploy.dev and you catch this error:
Type ‘typeof IamHeader’ is not assignable to type ‘VueConstructor
from src
The text was updated successfully, but these errors were encountered:
npm run deploy is working without ts-ignore & without errors
differences in tsconfig.dev.json vs tsconfig.json
«strictFunctionTypes»: false is not helped to me
Please minimize your reproduction to make sure your problem is actually caused by vue-class-component. e.g. Remove extra build tool / configuration (gulp, multiple tsconfig.json etc.), only include codes which causes this problem.
See how to make reproduction: https://new-issue.vuejs.org/?repo=vuejs/vue#why-repro
@ktsn ok I am working on it
Hi guys, any update about this issue?
@decentraliser I can’t reproduct this problem on another small project.
it happened to me when I deleted package-lock.json and /node_modules , then npm i .
not sure if I can reproduce it
afterwards I just cloned my repo in a new folder and everything worked
@decentraliser I just tried your way, but deleting node_modules folder & package-lock.json didn’t help me.
Closing until a minimal reproduction is provided. If you are able to provide it which clarify the problem is caused by vue-class-component, please open a new issue.
Just in case anyone else is getting similar «no overload matches this call» errors, I was having a similar issue when I was trying to import a component defined in vanilla JS.
The main thing is that the rule about needing to use Vue.extend(<>) applies to child components as well.
To fix it I just needed to change this:
My mistake which caused this:
I had same issue, however, I was able to fix it. Propably nobody else will have totally same retarded mistake as I made, but this might help in debugging.
This was causing TS2769 . Thanks to @ericksonc I tried his way to fix this. So I end up with following code:
Well, this did either work. I end up with ERROR in /. /HStockWidgetActions.vue.ts(29,2) . So this error was caused totally by faulty module. In my case the fault in this module was missing the extending of Vue.
Meaning by wrong code was following
while it supposed be
After this I just put back the «correct» code and it passed without problems.
Possible another solution
I remember also having this issue few weeks before also. When this happend after I switched node from 10 to 13 with nvm . Solution to this was just drop the node_modules folder and install again. Problem solved with that.
Just one question rises. Why the heck Javascript/TypeScript packages are so easy to break and why they dont have proper stacktrace to debug. 😑
Possible another solution
I remember also having this issue few weeks before also. When this happend after I switched node from 10 to 13 with nvm . Solution to this was just drop the node_modules folder and install again. Problem solved with that.
This helped me to solve my problem, to anyone finding this googling the error code. After double-checking my export s and extend s and my spelling of everything, and having the problem persist, refreshing my project packages with yarn install resolved this very annoying issue. Thank you @NikoGrano for the footnote!
@ktsn, can you reopen this issue?
Reproduction project
Problem code (as soon as updating vue-property-decorator from v8.4.2 to v9.1.2 & npm run lint or npm run test )
That isn’t a reproduction, though. A reproduction is a 5 file (or less) «hello world» project, so you can eliminate it’s not some other issue.
For anyone coming here and none of the above solutions worked for you I wanted to share why I was getting this error and how I fixed it. The errors being shown for me were not readily apparent and did not help narrow down the problem.
I had all working code and class based components working in my NuxtJS project. I added a global mixin computed property and then all these errors started showing up:
It was very confusing and I didn’t know why. I then started traversing down into the components being imported. All the spelling was correct and all components were being property extended.
Then I realized that one of the nested components had a Property name with the same name as the computed property I had in the mixin:
Once I removed the property value since it was no longer needed all of the TS errors went away:
I hope this was helpful for anyone else coming here by googling that TS error! Good luck!!
Источник
Ts2769 no overload matches this call the last overload gave the following error
Reading time В· 4 min
No overload matches this call error in TypeScript #
The error «No overload matches this call» occurs when we call a function and pass it a parameter that doesn’t match any of its specified overloads. To solve the error, make sure the function is being called with the correct number of arguments of the correct type, or use a type assertion.
Here are 2 examples of how the error occurs.
In the first example, we take only 1 parameter in the callback, but it expects a minimum of 2 parameters.
To solve the error, specify the correct number of parameters in the function’s definition.
In the second example, TypeScript gets confused about the type of the value we call the function with.
This is a valid function call, but the compiler has limitations, so we have to use a type assertion when calling the example function.
The as any syntax is called a type assertion and effectively turns off type checking for the specific parameter.
If the suggestions above did not help, the best way to solve the error is to understand its cause.
You might be getting the error when calling a function with overloads from a third party library or one that you have defined yourself, but the following applies either way.
Here is an example of a function that has 2 overloads:
The first two lines are called the overload signatures, and the third line is the function implementation.
The Date() constructor can be passed different arguments to create a Date object.
In the first signature, the function takes a timestamp ( number ) parameter and returns a Date object.
In the second signature, the function takes 3 comma-separated parameters of type number and returns a Date object.
Even though the line where we call the createDate function satisfies its implementation signature, because the function has 2 optional parameters, we get an error.
If you are getting the error when calling a function from a third-party module, open its type definitions. For example, in VSCode you can do that by pressing the ALT key and clicking on the function’s name with your mouse.
Now look at the overload signatures of the function — you can only call one of the function’s overload signatures, not its implementation signature.
The example function can be called with a single argument of type string , which satisfies the first overload signature.
The function can also be called with 2 arguments of type number , which satisfies the second overload signature.
The implementation signature of the function cannot be called directly, you have to call one of the overload signatures.
Conclusion #
The error «No overload matches this call» occurs when we call a function and pass it a parameter that doesn’t match any of its specified overloads. To solve the error, make sure the function is being called with the correct number of arguments of the correct type, or use a type assertion.
Источник
error TS2769: No overload matches this call. #2955
Hi 🙂
I’m contributing for open source project developing UI component of React-Native using below.
- React-Native
- Typescript
- Styled-components
While writing component using styled-components, I found error caused by style type property(like TextStyle , ViewStyle ) that is passed as props when running yarn lint && yarn tsc .
I don’t know why this happening.
Reproduction
Error message is like this.
‘. Type ‘(TextStyle | (TextStyle | < fontWeight: string; >)[] | null | undefined)[]’ is not assignable to type ‘RecursiveArray ‘. The types returned by ‘pop()’ are incompatible between these types. Type ‘TextStyle | (TextStyle | < fontWeight: string; >)[] | null | undefined’ is not assignable to type ‘false | TextStyle | RegisteredStyle
| RecursiveArray | null | undefined’. Type ‘(TextStyle | < fontWeight: string; >)[]’ is not assignable to type ‘false | TextStyle | RegisteredStyle
| RecursiveArray | null | undefined’. Type ‘(TextStyle | < fontWeight: string; >)[]’ is not assignable to type ‘RecursiveArray ‘. The types returned by ‘pop()’ are incompatible between these types. Type ‘TextStyle | < fontWeight: string; >| undefined’ is not assignable to type ‘false | TextStyle | RegisteredStyle
| RecursiveArray | null | undefined’. Type ‘< fontWeight: string; >‘ is not assignable to type ‘false | TextStyle | RegisteredStyle
| RecursiveArray | null | undefined’. Type ‘< fontWeight: string; >‘ is not assignable to type ‘TextStyle’. Types of property ‘fontWeight’ are incompatible. Type ‘string’ is not assignable to type ‘»normal» | «bold» | «100» | «200» | «300» | «400» | «500» | «600» | «700» | «800» | «900» | undefined’. Overload 2 of 2, ‘(props: StyledComponentPropsWithAs ): ReactElement , string | . 1 more . | (new (props: any) => Component )>’, gave the following error. Type ‘(TextStyle | (TextStyle | < fontWeight: string; >)[] | null | undefined)[]’ is not assignable to type ‘StyleProp
‘. Type ‘(TextStyle | (TextStyle | < fontWeight: string; >)[] | null | undefined)[]’ is not assignable to type ‘RecursiveArray ‘. 206 style=<[
node_modules/@types/react-native/index.d.ts:901:5 901 style?: StyleProp
The expected type comes from property ‘style’ which is declared here on type ‘IntrinsicAttributes & Pick
, «ref» | «style» | «onLayout» | «testID» | «nativeID» | . 27 more . | «textBreakStrategy»> & Partial , «ref» | . 31 more . | «textBreakStrategy»> & < . ; >& < . ; >& < . ; >‘ node_modules/@types/react-native/index.d.ts:901:5 901 style?: StyleProp
The expected type comes from property ‘style’ which is declared here on type ‘IntrinsicAttributes & Pick
, «ref» | «style» | «onLayout» | «testID» | «nativeID» | . 27 more . | «textBreakStrategy»> & Partial , «ref» | . 31 more . | «textBreakStrategy»> & < . ; >& < . ; >& < . ; >‘ Found 1 error. error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.»>
Environment
System:
- OS: macOS Catalina 10.15.2
- CPU: x64 Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
- Memory: 155.12 MB / 16.00 GB
- Shell: 5.7.1 — /bin/zsh
Binaries:
- Node: 13.5.0
- Yarn: 1.21.1
- npm: 6.13.4
npmPackages:
- styled-components: ^4.4.1 => 4.4.1
- @types/styled-components: ^4.4.1 => 4.4.1
The text was updated successfully, but these errors were encountered:
Источник
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.
No overload matches this call
No overload matches this call.
Overload 1 of 2, '(options: B): Promise<void>', gave the following error.
Argument of type 'A | B' is not assignable to parameter of type 'B'.
Type 'A' is not assignable to type 'B'.
Type 'A' is not assignable to type '{ async: true; }'.
Types of property 'async' are incompatible.
Type 'false | undefined' is not assignable to type 'true'.
Type 'undefined' is not assignable to type 'true'.
Overload 2 of 2, '(options: A): void', gave the following error.
Argument of type 'A | B' is not assignable to parameter of type 'A'.
Type 'B' is not assignable to type 'A'.
Types of property 'async' are incompatible.
Type 'true' is not assignable to type 'false | undefined'.
Enter fullscreen mode
Exit fullscreen mode
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:
Overload x of y, '(arguments): return type', gave the following error.
Enter fullscreen mode
Exit fullscreen mode
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:
function add(a: number, b: number): number {
return a + b;
}
Enter fullscreen mode
Exit fullscreen mode
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
function add(a: number, b: number): number;
function add(a: number, b: number, c: number): boolean;
function add(a: number, b: number, c?: number) {
if (c) return a + b === c
return a + b
}
Enter fullscreen mode
Exit fullscreen mode
The add
function now has two overloads. It can be confusing, but the first two lines are function signatures and the last is the actual implementation for the function. The top definition has priority, and the line under that is the overload: 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 unions.
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.
Types of property type
are incompatible
Argument of type '{ type: string };' is not assignable to parameter of type 'Schema'
Type '{ type: string; }' is not assignable to type 'Schema'
Types of property 'type' are incompatible.
Type 'string' is not assignable to type '"string" | "number"'
Enter fullscreen mode
Exit fullscreen mode
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 explains what «assignable to» 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 a number
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 literals vs string
type
One 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"'
.
const getType = () => "string";
const type = getType();
type TestType = { type: "string" | "number" };
// Type 'string' is not assignable to type '"string" | "number"'
const obj: TestType = { type }; // ❌ type: string
Enter fullscreen mode
Exit fullscreen mode
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.
const getType = () => "string" as const;
const type = getType();
type TestType = { type: "string" | "number" };
const obj: TestType = { type }; // ✅ type: 'string'
Enter fullscreen mode
Exit fullscreen mode
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
, the type will be the literal contents of the string.
let changingString = "Hello World";
// type is `string`: since variables defined with
// `let` are mutable, this *could* represent other
// values
const constantString = "Hello World";
// type is `"Hello World"`: this is a constant
// variable and can only represent one value
// using a method to change the string
// like `.reverse()` will simply change
// the type to a `string`
Enter fullscreen mode
Exit fullscreen mode
Conclusion
The TypeScript documentation has a good guide to understanding errors better, 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 minimal reproducible example (there’s a good guide by StackOverflow) 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.
If you enjoyed this post, I’d love to hear any feedback! Write a comment, leave a reaction (❤️, 🦄) and share around with your TypeScript friends who are pulling their hair out!
I’ve heard folks say, “write the blog post you wish that you’d found.” Well, this post is for anyone searching for an answer to a cryptic TypeScript error that first reared it’s head after installing the Material Design-compliant React Native UI library: react-native-paper.
The error
I like to keep a terminal window open with the TypeScript compiler running in watch mode (with a "tsc": "tsc"
npm script, this can be done with: npm run tsc -- -w
). When I first noticed this error, I found it taking up nearly the entire window:
The contents of the error is printed below:
src/ui/YPButton.tsx:24:10 - error TS2769: No overload matches this call.
Overload 1 of 2, '(props: Pick<Pick<ViewProps & { children: ReactNode; style?: StyleProp<ViewStyle>; theme: Theme; }, "children" | "testID" | "style" | ... 48 more ... | "onTouchEndCapture"> & { ...; } & { ...; } & { ...; }, "children" | ... 61 more ... | "contentStyle"> & { ...; }, context?: any): ReactElement<...> | Component<...>', gave the following error.
Type '{ children: ReactNode; styleName?: string; style?: any; onPress: () => void; mode: "text" | "outlined" | "contained"; uppercase: boolean; nativeID: string; }' is missing the following properties from type 'Pick<Pick<ViewProps & { children: ReactNode; style?: StyleProp<ViewStyle>; theme: Theme; }, "children" | "testID" | "style" | "onLayout" | ... 47 more ... | "onTouchEndCapture"> & { ...; } & { ...; } & { ...; }, "children" | ... 61 more ... | "contentStyle">': isTVSelectable, hasTVPreferredFocus, tvParallaxProperties, tvParallaxShiftDistanceX, and 3 more.
Overload 2 of 2, '(props: Pick<Pick<ViewProps & { children: ReactNode; style?: StyleProp<ViewStyle>; theme: Theme; }, "children" | "testID" | "style" | ... 48 more ... | "onTouchEndCapture"> & { ...; } & { ...; } & { ...; }, "children" | ... 61 more ... | "contentStyle"> & { ...; } & { ...; }, context?: any): ReactElement<...> | Component<...>', gave the following error.
Type '{ children: ReactNode; styleName?: string; style?: any; onPress: () => void; mode: "text" | "outlined" | "contained"; uppercase: boolean; nativeID: string; }' is missing the following properties from type 'Pick<Pick<ViewProps & { children: ReactNode; style?: StyleProp<ViewStyle>; theme: Theme; }, "children" | "testID" | "style" | "onLayout" | ... 47 more ... | "onTouchEndCapture"> & { ...; } & { ...; } & { ...; }, "children" | ... 61 more ... | "contentStyle">': isTVSelectable, hasTVPreferredFocus, tvParallaxProperties, tvParallaxShiftDistanceX, and 3 more.
24 <Button onPress={onPress} mode={mode} uppercase={uppercase} nativeID={testID} {...otherProps}>
My initial instinct was to begin adding the props that it had called me out for omitting (following is missing the following properties from type
in the error). However, these TV
related props weren’t listed as mandatory in the Paper docs, so why do I have to include them? Besides, it’s very unlikely this app will ever run on a TV.
Also concerning to me was the cryptic looking Prop type:
Pick<Pick<ViewProps & { children: ReactNode; style?: StyleProp<ViewStyle>...
Did I really want to invest in a library that was using such complex types for one of their most simple components? 😬
I turned to the source, and found that the Paper TypeScript Props for their Button component were in fact fine; concise and well-documented. If this wasn’t an issue with Paper, and it wasn’t occurring before I began using the library, what could be the culprit?
The solution: @types/react-native@0.57.65
On a hunch, and running out of other things to try, I noticed that my installed version of @types/react-native
(0.57.7) was quite a bit behind the latest patch release of the 0.57.* versions. I took a look at the released versions on npm and found that the latest available release for 0.57 was 0.57.65
. I installed it with the following command:
npm i @types/react-native@0.57.65 --save-dev
… once 👆 was installed and I’d started back up my TypeScript watch command, I was very relieved to finally see that familiar, comforting compiler output again: Found 0 errors. Watching for file changes.
Hopefully this tip can save you a few gray hairs.