Skip to content

Fix #4241, infer partially annotated function #11529

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

Conversation

HerringtonDarkholme
Copy link
Contributor

Fix #4241, and #6416, #9648, #10850

If a function expression has at least one parameter unannotated or has no parameter, it is contextually typed.

When a function is contextually typed, its annotated parameters are used to infer type arguments of its context. After that , for remaining parameters, they are typed contextually and make their corresponding type parameter from context fixed.

For proposed spec change, see #4241 (comment) .

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

I'll bring this to the design meeting and see what the rest of the team think about it.

The change looks OK to me but I don't know all the invariants that contextual typing is supposed to maintain. In particular, I don't know if the call to inferTypes is safe in the first loop.

Also, didn't existing tests change at all? I would expect to see a lot of any changing into actual types.

@HerringtonDarkholme
Copy link
Contributor Author

I have encounter a test change in which this is changed in a function with no argument. But that is fixed by enabling inference on functions with no argument.

I also run a simple regular expression search, grep -Pr '\(.*\([^:]+,[^:]+:.+\)' --include='*.ts', on test cases. It seems there are only few cases which has partially contextual typed function.

compiler/fatarrowfunctions and conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraintTransitively2.ts are two cases.

@ahejlsberg
Copy link
Member

@HerringtonDarkholme Thanks for your contribution. I like your core idea of initially considering partially annotated function expressions context sensitive and then later inferring from the parameters that actually have annotations, but the implementation has a few issues (I will call those out separately in the code). I'm going to put up a new PR that uses the same core idea, plus incorporates some additional fixes from #11600.

const isNullaryArrow = node.kind === SyntaxKind.ArrowFunction && !node.parameters.length;
return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow;
return !node.typeParameters && hasUntypedParameterOrNoParameter && !isNullaryArrow;
Copy link
Member

Choose a reason for hiding this comment

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

An issue here is that a function expression with fully annotated parameters is not considered context sensitive, which means it won't have a type inferred for this.

// infer type parameter from annotated arguments
if (isInferentialContext(mapper)) {
for (let i = 0; i < len; i++) {
if (declaredParameterTypes[i].type) {
Copy link
Member

Choose a reason for hiding this comment

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

This won't work when a function has an explicit this parameter because indices in the declaration are then off by one compared to indices in the signature. The right solution is to use the valueDeclaration of the parameter symbol to get to the declared signature.

@HerringtonDarkholme
Copy link
Contributor Author

Thanks! Waiting for #11673 !

@HerringtonDarkholme
Copy link
Contributor Author

Great!

@HerringtonDarkholme HerringtonDarkholme deleted the partial-annotation branch October 18, 2016 06:22
@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.

Parameter signatures of functions in object literals are not always inferred correctly.
4 participants