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

Suggestion: when compiling with noImplicityAny make 'this' have type '{}' where it previously had type 'any' #1740

Closed
danielearwicker opened this issue Jan 20, 2015 · 1 comment
Labels
Suggestion An idea for TypeScript

Comments

@danielearwicker
Copy link

This would be a breaking change, so might need to be a separate flag. However I suspect anyone using noImplicitAny would switch on that flag, so maybe it should just be normal behaviour for noImplicitAny.

If inside a class method foo I write:

foo() {
    $.get('/blah', blah => this.blah = blah);
}

The lambda correctly preserves the type of this to be the surrounding class, and so my class better have a property blah that is of the right type or the compiler will complain. All good.

If instead I write:

foo() {
    $.get('/blah', function() { this.blah = blah; });
}

Now this no longer refers to the class object, so it no longer works. This is fine - function has different behaviour.

The problem is that this has been given the type any.

You might argue that I asked the compile to do that by saying function() {... instead of using a lambda, so this wasn't an implicit any, as such.

Yes, in that example the problem is easy to spot thanks to the function keyword. But how about:

foo() {
    this.mouseEvents = {
        down() {
            this.mouseDown = true;
        },
        up() {
            this.mouseDown = false;
        }
    }
}

No function keywords, because I'm using ES6's nice abbreviation for an object literal with functions. Inside down(), this is again not the surrounding object but is the new object I'm assigning to this.mouseEvents. Sometimes that's what I want, but in this case it's not. The problem is again that this is of type any so the compiler checks nothing.

So the suggestion is to give this the type {} in these circumstances. In the (hopefully rare) cases where I genuinely do want to smuggle information into a function via untyped this, I will need to do my own explicit declaration at the start of the function:

var extraInfo: any = this;

But if it's a mistake (most cases), I'll find out when I try to access my class's properties/methods on {}.

For bonus points, in the object literal example, the type of this could be the type of the object literal (that's what it is at runtime). But I guess that might raise circularity difficulties. The core problem here is the implicit introduction of this: any.

@danquirk
Copy link
Member

It's possible that this could be a rule in #274 although the ideal solution is really just to address the issues in #513 and type 'this' more accurately. I'm gonna close this and make a note in #274.

@danquirk danquirk added the Suggestion An idea for TypeScript label Jan 20, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants