Skip to content

Elaborate type of invoked expression in error message #5784

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

Merged
merged 4 commits into from
Sep 14, 2016

Conversation

erictsangx
Copy link
Contributor

No description provided.

@msftclas
Copy link

Hi @erictsangx, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

In order for us to evaluate and accept your PR, we ask that you sign a contribution license agreement. It's all electronic and will take just minutes. I promise there's no faxing. https://cla.microsoft.com.

TTYL, MSBOT;

@msftclas
Copy link

@erictsangx, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR.

Thanks, MSBOT;

unionOfDifferentParameterTypes();// error - no call signatures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
!!! error TS2658: Cannot invoke an expression whose type is a union with incompatible call signatures.

var unionOfDifferentNumberOfSignatures: { (a: number): number; } | { (a: number): Date; (a: string): boolean; };
unionOfDifferentNumberOfSignatures(); // error - no call signatures
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this call get the new error too?

@sandersn
Copy link
Member

This is a nice improvement, although I'd rather see an elaboration of the original error, something like

Cannot invoke an expression whose type lacks a call signature.
  Type '{ (a: number): number } | { (a: string): Date }' has no compatible call signatures.

@DanielRosenwasser
Copy link
Member

I don't think this is a sufficient check; for instance, you shouldn't report a different error in the following case:

image

Basically, this is for people who are dumbfounded by the fact that each of their constituent types is callable but the result of the union is not callable. This new error message is even less clear because it throws more jargon into the mix for no reason.

I think if you also checked whether at least one of the constituent types had a call signature, that would be a sufficient condition to issue the new message.

@DanielRosenwasser
Copy link
Member

Also, can you add the test I showed above if it turns out that my suggested change doesn't affect any tests? Thanks!

@erictsangx erictsangx force-pushed the fixUnionTypeCallSignature branch 2 times, most recently from a63f800 to 19f9379 Compare November 26, 2015 11:04
@erictsangx
Copy link
Contributor Author

Thank you for the clarification, guys. It seems I was doing it wrong.
I have reworked the code and the error message.
The new error is thrown only if any constituent type is not callable. Otherwise, it should not throw TS2349: Cannot invoke an expression whose type lacks a call signature.

let unionCallSignatures: Signature[] = [];
let hasError = false;
forEach(unionApparentType.types, type => {
const eachCallSignature = getSignaturesOfType(type, SignatureKind.Call);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract the logic here out to a function called typeHasCallSignatures and place it next to typeHasConstructSignatures. Don't base the new function on typeHasConstructSignatures

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then use (apparentType.flags & TypeFlags.Union && forEach((<UnionType>apparentType).types, typeHasCallSignatures)

@erictsangx erictsangx force-pushed the fixUnionTypeCallSignature branch from 19f9379 to 8b3f46c Compare December 2, 2015 09:21
@erictsangx
Copy link
Contributor Author

Updated. I will create another pr for Not all types in '{0}' have compatible call signatures. If this pr has no other problems.

@erictsangx erictsangx force-pushed the fixUnionTypeCallSignature branch from 8b3f46c to 4737d12 Compare December 2, 2015 09:59
@@ -23,7 +23,7 @@ tests/cases/compiler/constructorOverloads4.ts(11,1): error TS2348: Value of type

(new M.Function("return 5"))();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'Function' has no compatible call signatures.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a regression

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically, we're not looking for call signatures here. We're looking for a construct signature, so we're not appropriately reporting an error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the semantics here? I don't think that class Function and function Function will merge (hence the duplicate identifier errors), so the error that changes should be based on only one of the definitions. The first definition has no call signatures, so if the error is based on the first definition, then it looks correct to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have misread the error span.

@DanielRosenwasser DanielRosenwasser changed the title Improve error message when calling value whose type is a union of types with call signatures Elaborate type of invoked expression Dec 2, 2015
@DanielRosenwasser DanielRosenwasser changed the title Elaborate type of invoked expression Elaborate type of invoked expression in error message Dec 2, 2015
@DanielRosenwasser
Copy link
Member

Actually, never mind my last comment. We can work on this change in this PR.

@@ -9438,7 +9443,12 @@ namespace ts {
error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
}
else {
error(node, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature);
if (apparentType.flags & TypeFlags.Union && forEach((<UnionType>apparentType).types, typeHasCallSignatures)) {
// TODO check Not all types in '{0}' have compatible call signatures.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just get rid of this portion entirely and use it in the separate PR. I'd rather not temporarily disable error messages until another PR comes in.

… union of types with call signatures

add diagnostic message 2658: Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures.

Closes microsoft#5640
@erictsangx erictsangx force-pushed the fixUnionTypeCallSignature branch from 4737d12 to 557433e Compare December 8, 2015 10:16
@erictsangx
Copy link
Contributor Author

@DanielRosenwasser updated

@sandersn
Copy link
Member

sandersn commented Dec 8, 2015

👍

@mhegazy mhegazy self-assigned this Sep 14, 2016
@mhegazy mhegazy merged commit 557433e into microsoft:master Sep 14, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Sep 14, 2016

manually merged. thanks

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants