Skip to content

Dangerous Property Initializers in Classes #5987

Closed
@kitsonk

Description

@kitsonk

This is valid, but seem very dangerous:

class One {
    two() {};
}

class Foo {
    two = this.one.two();
    one = new One();
}

The emit goes in order of declaration which will cause a runtime error:

var One = (function () {
    function One() {
    }
    One.prototype.two = function () { };
    ;
    return One;
})();
var Foo = (function () {
    function Foo() {
        this.two = this.one.two();
        this.one = new One();
    }
    return Foo;
})();

Activity

kitsonk

kitsonk commented on Dec 30, 2015

@kitsonk
ContributorAuthor

I suspect this got lost in the pile. Any thoughts, or is it just and edge case that isn't worth bothering with?

DanielRosenwasser

DanielRosenwasser commented on Dec 30, 2015

@DanielRosenwasser
Member

Sorry about that, this past month's been busy and naturally some people are out.

I wonder if this should fall under the umbrella of #2234.

changed the title [-]Dangerous Parameter Initializers in Classes[/-] [+]Dangerous Property Initializers in Classes[/+] on Dec 30, 2015
kitsonk

kitsonk commented on Dec 30, 2015

@kitsonk
ContributorAuthor

Clearly it is related to #2234, but I would suspect a lot of users would be "surprised" that they have to think about the ordering of a property initializers in a class, although I just checked the ES Stage 1 proposal for class properties and initializers and it appears that this would break there too, so the emit is valid. In that case, stupid is as stupid does and it would logically fall in the realm of use before initialization.

cc/@adidahiya

RyanCavanaugh

RyanCavanaugh commented on Jan 1, 2016

@RyanCavanaugh
Member

"Order of emit is order of declaration" is a must-have behavior for ES6 compat ES7+ compat as that would almost certainly have the same semantics.

I don't see why we wouldn't error here, though. We can treat these as if they were let declarations in terms of TDZ rules.

added
Effort: ModerateRequires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual".
on Jan 4, 2016
added this to the Community milestone on Jan 4, 2018
theseyi

theseyi commented on Mar 15, 2018

@theseyi

Is this a similar issue to the ffg being allowed in TS?

class Test {
  x:any = this.x;
}

I can't find any documentation that says you can reference this in a class field / property but TS allows this to compile and emits js, but looking at it seems odd.

emit:

var Test = /** @class */ (function () {
    function Test() {
        this.x = this.x;
    }
    return Test;
}());

http://www.typescriptlang.org/play/index.html#src=class%20Test%20%7B%0A%20%20x%3Aany%20%3D%20this.x%3B%0A%7D

theseyi

theseyi commented on Mar 16, 2018

@theseyi

@kitsonk Thoughts?

kitsonk

kitsonk commented on Mar 22, 2018

@kitsonk
ContributorAuthor

I don't know if it is similar. It is valid, though illogical. My opinion would be that it should be an error as well (sort of the same class as use before assigned).

JoshuaKGoldberg

JoshuaKGoldberg commented on Jan 12, 2019

@JoshuaKGoldberg
Contributor

The original code now correctly gives a type checking error! ✨

class One {
    two() {};
}

class Foo {
    two = this.one.two();
               ~~~ // Property 'one' is used before its initialization.ts(2729)
    one = new One();
}

However, x: any = this.x; is still allowed but shouldn't be.

added a commit that references this issue on Jan 13, 2019
cd88f6a

6 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Effort: ModerateRequires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual".Help WantedYou can do thisSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      Participants

      @DanielRosenwasser@kitsonk@chriskrycho@JoshuaKGoldberg@theseyi

      Issue actions

        Dangerous Property Initializers in Classes · Issue #5987 · microsoft/TypeScript