Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript interface: function as property - or - this in interface implementations

My problem is with functions in interfaces and the this keyword in the implementation.

Assume the following scenario:

I've got a class which implements a specific interface. The interface may be defined as following:

module Contracts
{
    export interface ISomeInterface
    {
        Foo: () => void;
    }
}

The implementation may look like this:

module MyClasses
{
    export class SomeClass implements Contracts.ISomeInterface
    {
        public SomeValue: string = "Some fancy value";

        public Foo() 
        {
            alert(this.SomeValue);
        }
    }
}

This works when I call it from the instance, like this:

var someClass = new MyClasses.SomeClass();
someClass.Foo();

Now, due to some circumstances the function is not being called like this, but within another context, causing this to be something completely different, resulting in this.SomeValue being undefined.

I've learned that when you want to access this correctly when a function is called within another context, you use the fat arrow like this:

public Foo = () =>
{
    alert(this.SomeValue);
}

(More info: https://github.com/Microsoft/TypeScript/wiki/%27this%27-in-TypeScript#use-instance-functions)

But this doesn't satisfy the interface. Foo is recognized as a property in the class, but the interface defines it as a method. Makes sense.

So how do I fix this the nice way?

like image 287
Daniel Schmid Avatar asked Sep 12 '26 20:09

Daniel Schmid


1 Answers

The simplest thing for you to do is to pass a bound function to your callback (or whatever).

For example:

let a: SomeClass = new SomeClass();
let boundFoo = a.Foo.bind(a);
boundFoo(); // this should be as you intended

More about the bind function in MDN


Edit

I checked your code in Playground and it seems ok.
The class implements the interface and the compiler does not complain.

like image 95
Nitzan Tomer Avatar answered Sep 15 '26 14:09

Nitzan Tomer