-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"TS2349: Cannot invoke an expression whose type lacks a call signature." when using union type containing a function #7960
Comments
But it is potentially an incorrect usage. The compiler only allows functions to be called, and you haven't convinced it that it's a function. If you run this code at runtime and the caller passes in a string for that prop, then this is going to blow up with a type error, which is exactly what TS is intended to prevent. So the correct thing to do is to check whether the prop is a function or not and handle both cases accordingly. interface BarProps {
failedContent?: string | string[] | (() => string);
}
class Bar {
props: BarProps;
render() {
const { failedContent } = this.props;
if (typeof failedContent === "function" && !(failedContent instanceof Array) {
let content = failedContent();
}
else {
throw new Error("Expected failedContent prop to be a function.");
}
}
} Note:
|
Thanks, I didn't know about your first note, that helped me fix a couple other compiler errors. What you wrote is almost exactly what I have, but my call is within a In a similar problem (the next prop down) it also can't distinguish between |
Your second point is the same as my second note, i.e. that One way is to check if (((arg): arg is JSX.Element => typeof arg === "object")(failedContent)) {
let content = failedContent; // JSX.Element
} The other simpler way is just assert it as a if (typeof failedContent === "object") {
let content = failedContent as JSX.Element;
} Perhaps open a separate issue for why |
The following code also results in an error TS2349: if (typeof this.method === 'function') {
let method = this.method(); // TS2349
} else {
let method = this.method; // Work
}
let method = typeof this.method === 'function' ? this.method() : this.method; // TS2349 The method has been declared in the class: export class DeamonService {
private method: string | (() => string);
// ... other code
} This only applies to a class method. If you create the same variable, the compiler calculates the correct type var method = angular.copy(this.method);
// method : string | (() => string)
if (typeof method === 'function') {
method(); // Work
}
if (typeof this.method === 'function') {
this.method(); // TS2349
} |
@cawa-93 this should be working as intended in TS 2.0 and later. please give it a try. |
@mhegazy, Yes. With tsc@2.0 there are no error. |
Using TS 2.0, this doesn't work either:
I can't find any way to have that |
@RyanCavanaugh Ok, refactored as |
You can get better type safety with |
@Arnavion you're right indeed, thanks! tried everything, and missed this.. |
Sorry to bring this back.
error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((destination?: T) => Readable) | ((destinati...' has no compatible call signatures. I can't understand why I am getting this error, since both |
- while testing we have methods using this method signature and it would be nice if we did not have define this. We were running into the issue as reported in microsoft/TypeScript#7960 So workaround was to do something like ``` const loginAction = userActions.login as ModuleAction<UserState>; ```
- while testing we have methods using this method signature and it would be nice if we did not have define this. We were running into the issue as reported in microsoft/TypeScript#7960 So workaround was to do something like ``` const loginAction = userActions.login as ModuleAction<UserState>; ```
TypeScript Version:
This is with TypeScript version 1.8.4.0 working in a TSX file in VS2015.
Code
The actual code is a big React component, so here is a sample with just the guts:
Expected behavior:
I would expect it to "just work" in a "native" fashion, meaning the compiler recognizes that the property can be a function, so a function call isn't necessarily an incorrect usage, and that explicit casting isn't necessary. Is this syntax/functionality not supported, or am I writing it incorrectly maybe?
Actual behavior:
It generates a compiler error.
The text was updated successfully, but these errors were encountered: