Skip to content

Improve Javascript intellisense type inference for cases where Object.assign(this, ...) is used with an object with known type information #16163

Open
@mjbvz

Description

@mjbvz

From @jj101k on May 28, 2017 10:16

  • VSCode Version: 1.12.2 (19222cdc84ce72202478ba1cec5cb557b71163de)
  • OS Version: macOS Sierra 10.12.5 (16F73)

Given the Javascript code:

class Foo {
    constructor() {
        Object.assign(
            this,
            {
                bar: "abc",
            }
        );
        this.foo = "def";
    }
}

var f = new Foo();
console.log(f.foo);
console.log(f.bar);

If you hover over f.foo, it will tell you that it's a string. If you hover over f.bar, it will say it's "any". They should both say "string".

Object.assign is a fairly common way of setting several properties with a bit less copy/paste. In cases where an object without known type information is used as the last argument it isn't possible to statically infer appropriate types for the modified object ("this", here) and equivalently the object that Object.assign returns. Where type information of the last argument is known, it is safe and appropriate to import all of that into the type information for the object, as if a series of direct assignments had been done.

Caveats: In Javascript (perhaps not Typescript) it's possible that further unknown properties are present on any given object, so it would be appropriate to void all inferred type information which is not between Object.assign and the end of the constructor. If Object.assign is used outside a constructor (on a named object) it should void all inferred types entirely, because the type information could be entirely different before and after. The same should be true if Object.assign is conditionally called in the constructor. The only exception should be when all arguments after the first have known final type information, eg. an immediate object.

For practical purposes, Object.assign(foo, bar, {baz: 1}) should be considered equivalent to for(name in bar) if(bar.hasOwnProperty(name)) foo[name] = bar[name]; foo.baz=1;.

Copied from original issue: microsoft/vscode#27397

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureDomain: JavaScriptThe issue relates to JavaScript specificallySuggestionAn idea for TypeScriptVS Code TrackedThere is a VS Code equivalent to this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions