Maintaining Context in TypeScript classes

TypeScript is generally pretty good at persisting this in functions but there are certain circumstances where you can (either accidentally or deliberately) get a class function to run in the wrong context.

class Example {
  private name = 'class context';

  public printName() {
    console.log(this.name);
  }
}

var example = new Example();
example.printName();
// => 'class context'
example.printName.call({ 
  name: 'wrong context' 
});
// => 'wrong context'

The most common scenario where I have accidentally caused this behaviour is where a function is bound to a click handler in Knockout and is executed in the context of the DOM element instead of the containing class.

In JavaScript you can always use myFunction.bind(this) to force the context but having to do that in the TypeScript constructor feels messy…

class Example {
  private name = 'class context';

  constructor() {
    this.printName = this._printName.bind(this);
  }

  private _printName() {
    console.log(this.name);
  }
}

var example = new Example();

example.printName();
// => 'class context'
example.printName.call({ 
  name: 'wrong context' 
});
// => 'class context'

Thankfully there’s an easy way to get TypeScript to correctly play ball.  Instead of defining the function inline, assign a lambda expression to a public class variable:

class Example {
  private name = 'class context';

  public printName = () => {
    console.log(this.name);
  }
}

var example = new Example();

example.printName();
// => 'class context'
example.printName.call({ 
  name: 'wrong context' 
});
// => 'class context'

JS Bin on jsbin.com

Much neater!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s