Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript object literal "this" keyword

What's the expected behavior when using this inside a function in an object literal?

For example, let's say I have a type foo that only has a function named bar and no other property on it. But in the fooObj.bar method, I'm able to access this.baz (where baz is not a property on type foo) I see no error. Shouldn't typescript error out, as fooObj does not have baz on it?

type foo = {
    bar(): void;
}
var fooObj: foo = {
    bar: () => {
        // TS does not error out when I access this.baz
        console.log(this.baz);
    }
} 
like image 342
Arvind Venkataraman Avatar asked Oct 26 '16 17:10

Arvind Venkataraman


People also ask

What is object literal in TypeScript?

When you create an object literal with {...} syntax, TypeScript will consider it to be a new object type, or type shape, based on its properties. That object type will have the same property names and primitive types as the object's values. Accessing properties of the value can be done with either value.

How do you use this in TypeScript object?

The main way to deal with the this object in traditional functions is to pass it in as the first parameter of a function and then set a type to it by defining an interface for the type. TypeScript will ignore the this parameter and treat it as if it doesn't exist. It's only used for setting the data type of this .

Can an object be literal?

Yes. In the object literal notation, an object description is a set of comma-separated name/value pairs inside curly braces. The names can be identifiers or strings followed by a colon. Save this answer.

Can you use this in an object JavaScript?

“this” is not bound In JavaScript, keyword this behaves unlike most other programming languages. It can be used in any function, even if it's not a method of an object. The value of this is evaluated during the run-time, depending on the context.


3 Answers

Setting the "noImplicitThis": true compiler option is how you would enable this functionality now. This pull request enabled typed this in object literals. Aleksey L originally suggested this compiler option in a comment on the question, but at the time it didn't function that way.

like image 164
alienriver49 Avatar answered Sep 30 '22 18:09

alienriver49


You’re using an arrow function, which has lexical this.

The shorthand for a non-arrow function property in an object literal is even shorter, though:

var fooObj: foo = {
    bar() {
        console.log(this.baz);
    }
}
like image 25
Ry- Avatar answered Sep 30 '22 19:09

Ry-


This answer was true at the time of the question. This have since changed with new versions of typescript and target javascript versions.

You are asking typescript to infer that this is fooObj.

Typescript binds this by creating a local variable _this, that is bound to the this-context where the fat-arrow is declared. And in your case, this is the global scope, which is any. This is what it gets compiled into:

var _this = this;
var fooObj = {
    bar: function () {
        // TS does not error out when I access this.baz
        console.log(_this.baz);
    }
};

This is how it looks like within a class:

class Bar
{
    private var = 23;
    public makeSound = () => console.log(this.var) 
}

// Compiles into:

var Bar = (function () {
    function Bar() {
        var _this = this;
        this.var = 23;
        this.makeSound = function () { return console.log(_this.var); };
    }
    return Bar;
}());
like image 28
Alex Avatar answered Sep 30 '22 18:09

Alex