David Sherret
David Sherret

Reputation: 106650

Is a constraint on function context possible?

As an example, say I have this code:

class MyClass {
    constructor(public myText: string) {
    }
}

// enforce the context to be of type MyClass for this function
function myFunction() {
    alert(this.myText);
}

var myObject = new MyClass("Hello");
myFunction.call(myObject);              // good
myFunction();                           // bad

Is there any way, in TypeScript, to constrain the this variable to always be an object of class MyClass? That would be useful for cracking down on some bugs at compile time.

Upvotes: 1

Views: 139

Answers (2)

basarat
basarat

Reputation: 275867

It's possible in TypeScript 2.0+. You use a this: Type annotation as the first argument to the function:

class MyClass {
    constructor(public myText: string) {
    }
}

// enforce the context to be of type MyClass for this function
function myFunction(this: MyClass) {
    alert(this.myText);
}

var myObject = new MyClass("Hello");
myFunction.call(myObject);              // good
myFunction();                           // bad

Upvotes: 2

WiredPrairie
WiredPrairie

Reputation: 59763

If you can't pass in the object reference directly to the function rather than rely on the this being correct, below is a slightly different approach that you might be able to use in some cases:

module Test {
    export class Example {
        Test1(): void { 
           // code here
        }
    }

    export function myFunction():void {
        if (this instanceof Example) {
            var asExample: Example = <Example>this;
            asExample.Test1();
        }   
    }   
}

var ex = new Test.Example();
Test.myFunction.call(ex);
Test.myFunction();

By using instanceof, you can limit the callers to only objects that are actually instances of Example as shown above. You could make it a one liner as well to do a type check and cast:

export function myFunction():void {
    var that = assertType<Example>(this, Example);
    that.Test1();
}   

function assertType<T>(obj:any, cls: any): T {
    if (obj instanceof cls ) {
            return <T>obj;
    }
    alert("Type mismatch");
    return null;
    //throw new Error('Type mismatch');
}

Upvotes: 1

Related Questions