Code insight in cast object literal does not reflect cast type

Topics: General
Jul 11, 2013 at 1:40 PM
Edited Jul 11, 2013 at 1:44 PM
Consider some code like this:
declare module MyApp.foo {
    export interface IMyClass {
        initialized?: bool;
        onDestroy? (): void;
    }
}

var myClass = <MyApp.foo.IMyClass>{
    doSomething: function() {
        var temp = this;
    }
} 
Within the doSomething function of the object literal, if I type "this.", I expect the IDE to recognize that "this" is of type MyApp.foo.IMyClass. This is not the case. For whatever reason, the IDE thinks "this" is of type "any". You can confirm this by inspecting the type of the "temp" local variable.

I'm fairly sure this is a bug, since obviously it should see "temp" as type MyApp.foo.IMyClass.

Also, may be a related issue but I'd expect the compiler to be flagging that whole object literal as invalid because it doesn't implement the IMyClass interface yet. That said, adding the initialized and onDestroy members of the interface doesn't change the fact that it still sees temp as type "any".

Thanks,

Brian
Coordinator
Jul 11, 2013 at 5:11 PM
I'm not sure if 'this' gets contextually typed outside of class definitions. With class definitions, we're reasonably confident of what the type of 'this' is, even though the actual type of 'this' at runtime is based on how the function that uses it is called. We've thought about doing some other cases, like the one you mention, for the time being we don't type 'this' except class definitions.

Perhaps a better solution long-term is being able to type 'this' from the function, so that we can enforce that 'this' has been bound correctly at the callsite.
Jul 11, 2013 at 5:23 PM
I see what you mean now. This is part of the reason that CoffeeScript uses @ to reference this. When used with single or fat arrows, it allows @ to be bound either to whatever "this" references (for ->) or bound to the scope in the containing object (=>).

Regardless, I suppose it's not a huge deal to just do something like var me : MyType = this;, and then use "me" to gain relevant code completion.

Thanks,

Brian
Jul 15, 2013 at 4:57 AM
Just to add though, a deeper issue may be the fact that the compiler doesn't seem to really recognize that the object is of type IMyClass, since it should flag the object as not implementing the interface in this case. It doesn't, so it's almost like casting the object to the type isn't having any real effect at all.
Coordinator
Jul 15, 2013 at 1:58 PM
Which part of the interface isn't being implemented?
Jul 15, 2013 at 2:43 PM
You're right! I forgot that I had the two fields in the interface marked optional. When I make them required, it flags it correctly. Sorry about that!
Dec 13, 2013 at 4:30 AM
Just wanted to revisit this. I'm not sure if issues within Visual Studio are appropriate here, but a cast object literal still gets no Intellisense or code completion. I understand the previous issue about determining "this" within a method of an object literal. But properties and methods of the type to which the object literal itself is cast should certainly be available for Intellisense, yes? Or does anyone know if this is possibly an issue in VS 2012 that is fixed in VS 2013?