Skip to content
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

Prefer constraint type for object literal completion #14197

Closed
wants to merge 6 commits into from

Conversation

asvetliakov
Copy link

Fixes #9900
Fixes #12968

Store constraint type when inferring and prefer it when resolving contextual type for completion.
I'm not sure what i'm doing it by correct way, anyway i just want to move these issues forward 😃

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Feb 21, 2017

I feel like a better fix would be for the language service to use the apparent type of the contextual type when it comes to completions (but only if the contextual type is not a primitive type).

It used to be the case that the language service's concept of getContextualType was intermingled with the apparent type (and was made explicit with d8d72aa).

const args = getEffectiveCallArguments(callTarget);
const argIndex = indexOf(args, arg);
if (argIndex >= 0) {
const signature = getResolvedOrAnySignature(callTarget);
return getTypeAtPosition(signature, argIndex);
const type = getTypeAtPosition(signature, argIndex);
if (completion && type && type.flags & TypeFlags.Object && (<ObjectType>type).constraintType) {
Copy link
Member

Choose a reason for hiding this comment

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

This actually won't work for intersection types or type parameters that are constrained by other type parameters.

Copy link
Author

Choose a reason for hiding this comment

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

Can you provide me few cases?
I tried following:

interface X {
  a?: string;
  b?: string;
  abc?: string;
  // k: number;
}

interface X2 {
  e?: string;
  k?: number;
}
interface Complex<T> {
  a?: number;
  b?: T;
}

declare function foo<T extends X & X2>(x: T): any
declare function goo<K, T extends Complex<K>>(a: K, b: T): any;

foo({ // OK });
goo("", { // OK });

@asvetliakov
Copy link
Author

asvetliakov commented Feb 21, 2017

The completion flow is already calling getApparentType in few places, but they don't return constraint type because object literal is being created as totally new anonymous type object. Not sure how to get correct type in this case.

@asvetliakov
Copy link
Author

@DanielRosenwasser
I tried to use getApparentType approach, but object literals in function arguments are being created with new anonymous object type and don't contain necessary flag TypeVariable with resolvedBaseConstraint property. I tried to fill this information in createObjectLiteralType() or in getInferredType() but this broke checker completely - looks like it doesn't expect constraint type inferring for these object literals. (it even was not able to compile)
Let me know if you have any ideas

@microsoft microsoft deleted a comment from msftclas Sep 27, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Nov 7, 2017

This is stale by now. @andy-ms was looking into something similar recently.

@mhegazy mhegazy closed this Nov 7, 2017
@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