To Arrow Function or not to Arrow Function

If you have used TypeScript you are probably aware of the compiled outcome of an Arrow Function (section 4.9.2 of the TypeScript Language Specification). The idea behind using () => {…}; instead of function(){…}; is to have access to the object represented by this in the outer scope, which is what you would expect when using a C# lambda. Of course this feature is particulalry useful in JavaScript because this holds a reference to the object to which a function was applied or called, and more often than not the this inside the function's execution context ends up being different from the one in the outer execution context.

When using an Arrow Function, TypeScript automatically assigns this to a separate variable in the outer execution context (called _this), which can be accessed by the function that results of the compilation of the Arrow Function through its closure. As the previous sentence was probably not the simplest one to digest, take the following TypeScript code snippet as an example:

The resulting JavaScript is:

As you can see, partialAdd stores this in the local _this variable which is accessible from the function that is returned through its closure. On the other hand, partialAdd2 uses this as the variable, but as I mentioned before this might not be "an instance of MyClass" but something completely different instead.

Complex Cases

You could (wrongly) deduce that every time you need access to the outer this inside the function you should use an Arrow Function, but what if you need to use both the outer this and the object on which the function was applied? That could be a usual situation in an event handler, which applies the callback functions to the target DOM elements when handling the event (for the sake of the example assume that there is no way to other way to access the DOM element other than this).

In these cases, it is important to understand what the compiler is doing underneath the hood. The two common approaches that would lead to errors are:

  1. Using an Arrow Function: this would cause TypeScript's this to shadow the compiled JavaScript's this, not allowing you to access the DOM elements that was clicked inside the click handler.
  2. Using a function literal: this would cause the outer this to not be accessible, which is unexpected for developers used to C#.

The Answer

One possible (and simple) solution to this is the usual workaround (that = this):

The following figures show that TypeScript's type inference system confirms the comments from the previous code snippet:

this can be an instance of any type, as it depends on the object on which the function was called

image

that is an instance of MyClass

image

Conclusion

This is not a complex issue, but is one that I've seen a couple of times while working with TypeScript, so hopefully if you ever run into it you will be able to solve it in no time.