Skip to content

Intellisense missing for generic type extending an all partial type #28470

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

Closed
AviVahl opened this issue Nov 11, 2018 · 8 comments · Fixed by #33937
Closed

Intellisense missing for generic type extending an all partial type #28470

AviVahl opened this issue Nov 11, 2018 · 8 comments · Fixed by #33937
Labels
Domain: Completion Lists The issue relates to showing completion lists in an editor Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Milestone

Comments

@AviVahl
Copy link

AviVahl commented Nov 11, 2018

TypeScript Version:
3.1.3 and 3.2.0-dev.20181110

Search Terms:
Intellisense suggestions generic type

Code

interface Options {
    someFunction?: () => string
    anotherFunction?: () => string
}

export class Clazz<T extends Options> {
    constructor(public a: T) {
    }
}

new Clazz({

// ctrl + space on above line does not provide any suggestion
// it does when:
// - making some/anotherFunction required instead of optional (in Options)
//   OR
// - giving constructor's first param a type of `T | Options`
})

Expected behavior:
suggest someFunction and anotherFunction.

Actual behavior:
no suggestions

Playground Link:
http://www.typescriptlang.org/play/#src=interface%20Options%20%7B%0D%0A%20%20%20%20someFunction%3F%3A%20()%20%3D%3E%20string%0D%0A%20%20%20%20anotherFunction%3F%3A%20()%20%3D%3E%20string%0D%0A%7D%0D%0A%0D%0Aexport%20class%20Clazz%3CT%20extends%20Options%3E%20%7B%0D%0A%20%20%20%20constructor(public%20a%3A%20T)%20%7B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Anew%20Clazz(%7B%0D%0A%0D%0A%2F%2F%20ctrl%20%2B%20space%20in%20line%2012%20does%20not%20provide%20any%20suggestion%0D%0A%2F%2F%20it%20does%20when%3A%0D%0A%2F%2F%20-%20making%20some%2FanotherFunction%20required%20instead%20of%20optional%20(in%20Options)%0D%0A%2F%2F%20%20%20OR%0D%0A%2F%2F%20-%20giving%20constructor's%20first%20param%20a%20type%20of%20%60T%20%7C%20Options%60%0D%0A%7D)%0D%0A

Related Issues:

@weswigham weswigham added Domain: Completion Lists The issue relates to showing completion lists in an editor Experience Enhancement Noncontroversial enhancements labels Nov 12, 2018
@parzh
Copy link

parzh commented Nov 28, 2018

Looks like I also encountered this issue, so +1. Hope, this playground is useful:

type Direction = "up" | "down" | "left" | "right";

type MovementDescriptor<Dir extends Direction> = {
    [D in Dir]: true;
};

// NB: The error here is that the `MovementDescriptor` type
// does not suggest type parameter autocompletion on Ctrl + Space
// (to test that, change type parameter to "" and press Ctrl + Space with cursor inside the parens),
// while all the compile errors occur just fine as expected
// (to test that, try making an typo, e.g. changing "left" to "let").
interface MovementUp extends MovementDescriptor<"up" | "left"> { }

const up: MovementUp = {
    down: true, // compile error is expected
}; 

@cspotcode
Copy link

I'm hitting this as well. Here is our use-case:

Our codebase builds large JSON API responses from multiple partial objects that we splat together. I'd like to have Intellisense for property names; we use verbose and inconsistent property names. But I'd also like some validation that, when the partial objects are splatted together, the result includes all properties. We don't want to accidentally omit anything.

So I need some way to:
a) get tab-completion for property names
b) let us omit properties when creating these partial objects
c) infer which properties have been specified so we can prove that the merged object contains all necessary properties

Naively, I tried inferring the type of each partial object via function partialApiResponse<T extends Partial<ApiReponseJson>(t: T) {return t} But Intellisense doesn't offer any suggestions.

@cspotcode
Copy link

cspotcode commented Dec 7, 2018

I noticed another behavior that suggests this is an unintended bug rather than an intentional limitation.

playground link

interface Foo {
    a_a: boolean;
    a_b: boolean;
    a_c: boolean;
    b_a: boolean;
}
function partialFoo<T extends Partial<Foo>>(t: T) {return t}
partialFoo({
    // <-- Ctrl-Space shows empty completion list.  Typing additional letters continues to show empty list.
    // *BUT* if you type the letter "a" *first*, you see a completion list, which then narrows as you type.
});

EDIT: Someone on reddit gave me a workaround: infer the keys union and type the argument as Partial<> & Pick<>:

partialFoo<T extends keyof Foo>(part: Pick<Foo, T> & Partial<Foo>): Pick<Foo, T> {return t;}

@HaloWang
Copy link

Come from #29180 with VSCode version 1.31.1. This problem still exist.😫

@HaloWang
Copy link

#306

@RyanCavanaugh RyanCavanaugh added the Suggestion An idea for TypeScript label Mar 7, 2019
@maxfontana90
Copy link

maxfontana90 commented May 15, 2019

I found a similar issue with a generic interface. It doesn't infer prop names even if its explicitly declared. Is this ok?

@parzh
Copy link

parzh commented May 16, 2019

@maxfontana90 In your case it is fine, since by stating that someImmutableGenericObject is a GenericObject you remove all the information about its properties, that might have otherwise be inferred. Try removing : Readonly<GenericObject>, this might bring IntelliSense back.

Also, technically this object is neither immutable (you can mutate its state), nor a Generic. See the meaning of the latter term here.

@AviVahl AviVahl mentioned this issue Jul 10, 2019
timsuchanek added a commit to timsuchanek/TypeScript that referenced this issue Jul 12, 2019
timsuchanek added a commit to timsuchanek/TypeScript that referenced this issue Aug 14, 2019
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Aug 16, 2019
timsuchanek added a commit to timsuchanek/TypeScript that referenced this issue Sep 11, 2019
timsuchanek added a commit to timsuchanek/TypeScript that referenced this issue Sep 11, 2019
@KillyMXI
Copy link

I think I have an issue related to this.

interface IBase {
  /** Base property */
  readonly a: number
}

interface ISpecialX extends IBase {
  /** Property X */
  readonly x: number
}

interface ISpecialY extends IBase {
  /** Property Y */
  readonly y: number
}

type SomethingSpecial = ISpecialX | ISpecialY;

export function doSomething(input: SomethingSpecial): void {}

And then:

import { doSomething } from '...';

doSomething({ a: 1, x: 2 });

Here, TypeScript language server can report a wrongly formed object passed as an argument (omit property a - get a type mismatch report).
But IntelliSense tooltip only shows documentation for properties from special interfaces, namely property x in this case. For the property a it shows only information inferred from usage.

andrewbranch added a commit that referenced this issue Oct 17, 2019
* fixes #30507

* Add test case for generic Partial type

* Fixes #28470

* Simplify contextFlags binary check

* Add string literal completion test

* Fix ContextFlags typings

* Speed up inference expression for completion

* Fix baseline merge

* Make contextFlags internal

* Reapply readonly array changes

* accept baselines

* Fix generic completion tests

* Re-merge ContextFlags

* Don’t change type during inference

* Fix typos and superfluous undefined arguments

* Add test for completions in unconstrained generic object literal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: Completion Lists The issue relates to showing completion lists in an editor Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants