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

Check property declarations in JS #27023

Open
shrinktofit opened this issue Sep 11, 2018 · 6 comments
Open

Check property declarations in JS #27023

shrinktofit opened this issue Sep 11, 2018 · 6 comments
Labels
Bug A bug in TypeScript
Milestone

Comments

@shrinktofit
Copy link

shrinktofit commented Sep 11, 2018

Recently I found it's helpful to add JSDOC style comment to hint my IDE the variable's type.

For example, If I add comment to a variable:

function fx(jsonAsset) {
   /** @type {import("a-dts-file-describes-the-type-of-the-json-object").Type} */
    const typedObject = jsonAsset.json;

    // IDE will give the member list of the type
    typedObject.
}

My IDE(Visual Studio Code Lastest) would correctly identify the type of typedObject.
So that it give me a very nice intelligent prompt. Even when I enable the type check through // @ts-check, it will give the type errors.

This feature is helpful to me and my project. It's written in Javascript(although we will try to rewrite it using Typescript in future but not for now).

We are using Babel with a plugin called transform-class-properties means that we can declare class member in ES6 class just like Typescript does:

class C {
    /* @types {HTMLCanvasElement} */
    @decorator(/* ... */)
    canvas = null;
}

But when I add similar comment to canvas declaration, it can not be recognized by IDE. The IDE seems like only decides the type through its initializer. Could you support this feature please?

@shrinktofit
Copy link
Author

shrinktofit commented Sep 11, 2018

Update: It seems more like a BUG?

class Test {
    /**
     * @type {HTMLCanvasElement}
     */
    _canvas; // IDE knows its type
}

and

class Test {
    /**
     * @type {HTMLCanvasElement}
     */
    _canvas = document.createElement('canvas'); // IDE knows its type
}

all take effect, but

class Test {
    constructor() {
        this._canvas = document.createElement('canvas'); // Because this assignment
    }
    /**
     * @type {HTMLCanvasElement}
     */
    _canvas; // IDE no longer knows its type, as "any"
}

doesn't take effects.

@AlCalzone
Copy link
Contributor

AlCalzone commented Sep 11, 2018

Try this (might require typescript@next due to a recently fixed bug):

class Test {
    constructor() {
        /**
         * @type {HTMLCanvasElement}
         */
        this._canvas = document.createElement('canvas');
    }
}

@shrinktofit
Copy link
Author

Try this (might require typescript@next due to a recently fixed bug):

class Test {
    constructor() {
        /**
         * @type {HTMLCanvasElement}
         */
        this._canvas = document.createElement('canvas');
    }
}

This works fine. However, how to turn

class Test {
    constructor() {
        this._canvas = document.createElement('canvas'); // Because this assignment
    }
    /**
     * @type {HTMLCanvasElement}
     */
    _canvas; // IDE no longer knows its type, as "any"
}

work?

@shrinktofit
Copy link
Author

shrinktofit commented Sep 12, 2018

@andy-ms I think typescript itself can recognize the type but IDE can't.
Given:

class Test {
    constructor() {
        this._canvas = document.createElement('canvas');
    }
    /**
     * @type {HTMLCanvasElement}
     */
    _canvas;
}

The following statement's error can be recognized, underlined by a wave line:

this._canvas = 0; // Error is occured once @ts-check is enabled:
                           // Cannot assign number 2 to type HTMLCanvasElement.

But:

  • When I move my mouse onto _canvas, IDE shows that it has any type;
  • When I write _canvas., no member list is shown.

@shrinktofit shrinktofit changed the title Add comment-style type hint support for class member Add JavaScript type checking support for class member Sep 12, 2018
@shrinktofit shrinktofit changed the title Add JavaScript type checking support for class member Add JavaScript file type checking support for class member Sep 12, 2018
@shrinktofit
Copy link
Author

shrinktofit commented Sep 12, 2018

Update: It's fun:

Working:

image

Not Working:

image

The difference is the order of member declaration.

Source code:

class Test1 {
    constructor() {
        this._canvas = document.createElement('canvas');
    }

    /**
     * @type {HTMLCanvasElement}
     */
    _canvas;
}

class Test2 {
    /**
     * @type {HTMLCanvasElement}
     */
    _canvas;

    constructor() {
        this._canvas = document.createElement('canvas');
    }
}

@ghost ghost added the Bug A bug in TypeScript label Sep 12, 2018
@RyanCavanaugh RyanCavanaugh assigned ghost Oct 9, 2018
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.2 milestone Oct 9, 2018
@ghost
Copy link

ghost commented Oct 11, 2018

@sandersn Above seems to be working now, but not:

class Test1 {
    x;
    constructor() {
        this.x = 0;
    }
}

which I think should succeed even in --noImplicitAny mode since we infer types from assignments in JS.

It looks like the class fields proposal allows fields without initializers. I think we should be able to infer a type in this case. It looks like currently in getTypeOfVariableOrParameterOrPropertyWorker we have separate paths for binary expressions and property declarations -- would be nice to merge those so we could handle cases like this.

@ghost ghost added Bug A bug in TypeScript and removed Bug A bug in TypeScript labels Oct 11, 2018
@ghost ghost assigned sandersn and unassigned ghost Oct 11, 2018
@sandersn sandersn changed the title Add JavaScript file type checking support for class member Check property declarations in JS Oct 12, 2018
@sandersn sandersn modified the milestones: TypeScript 3.4.0, Backlog Mar 13, 2019
@sandersn sandersn removed their assignment Jan 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants