TS2349
TypeScript Programming Language
Severity: ModerateWhat Does This Error Mean?
TypeScript error TS2349 means you are trying to call something as a function, but TypeScript knows it is not callable. The full message is: 'This expression is not callable. Type X has no call signatures.' This happens when you accidentally call a value that is a plain object, number, string, or non-function type as if it were a function. Common causes are missing parentheses in a function call that returns a function, or calling a property that holds a value instead of a function.
Affected Models
- TypeScript 4.x
- TypeScript 5.x
- VS Code
- WebStorm
- Any TypeScript project
Common Causes
- Calling a variable that holds a non-function type (a number, string, object, or boolean) using () syntax
- A function that returns a function is called without parentheses, giving you the inner function as a value instead of calling it
- A class property is a value type but is accidentally called as a method with ()
- A type assertion or generic is resolving to a non-callable type when a function type was expected
- An imported item is a constant or value, not a function, but it is used with function call syntax
How to Fix It
-
Hover over the expression being called in VS Code. The tooltip shows its type. If the type is not a function type (does not show (...) => ...), you are calling a non-function.
A function type in TypeScript looks like: () => void or (x: number) => string. If the type shown is number, string, object, or similar, it cannot be called.
-
Check if you are missing parentheses in a function call chain. For example, if getHandler() returns a function, getHandler()() calls the returned function. Writing getHandler()() instead of getHandler() fixes double-call patterns.
This is common with factory functions: const handler = getClickHandler(). Then call handler() not getClickHandler.
-
Check for naming conflicts. If you have a variable with the same name as a function (e.g., const onClick = 5; and you try to call onClick()), the variable shadows the function.
Use different names for variables and functions. TypeScript will highlight the conflict but the error message may not make it obvious at first.
-
Check that the property you are calling is actually a method on the class or object. Use IntelliSense to see the property's type. If it is a data property (not a function), do not add () when accessing it.
Example: if user.name is a string, writing user.name() is TS2349. Just use user.name without parentheses.
-
If the type is a union that includes both functions and non-functions, narrow the type with a typeof check before calling. Example: if (typeof handler === 'function') { handler(); }
Type narrowing tells TypeScript which branch of the union is active, making the call safe.
When to Call a Professional
TS2349 is a TypeScript type error that you fix in your source code. No external tools or services are needed. The fix is understanding what type the expression actually has, and either changing the type or changing how you use it.
Frequently Asked Questions
Why does TypeScript catch this error but JavaScript does not?
JavaScript allows calling any value with () at runtime — it simply throws a 'not a function' TypeError when it actually executes. TypeScript catches this at compile time by analyzing the types statically before the code runs. This is one of TypeScript's core benefits: finding type errors at compile time rather than discovering them as runtime crashes in production.
What does 'has no call signatures' mean in the error message?
A 'call signature' in TypeScript is the type information that describes how a function can be called: its parameters and return type. Function types have call signatures; non-function types do not. When TypeScript says 'has no call signatures', it means the type of the expression you are trying to call does not describe any function — it is a plain value type that cannot be invoked.
Can interfaces cause TS2349?
Yes — if an interface defines a property as a specific value type (like count: number) and code tries to call it as count(), TypeScript raises TS2349. Also, if two interfaces are merged and one defines a property and the other defines a method with the same name, the merged type can become non-callable for that name. Check for interface merging issues if the error appears on a well-typed library type.