Skip to content

Regression: ERROR TS2564: Property 'module/A#c' has no initializer and is not assigned in the constructor before 'this' is used or returned. #2576

Open

Description

@jtenner

Link: here

Minimal reproduction: (as far as I can reduce it)

class B {}
class A {
  b: B;
  c: B;
  constructor() {
    // this should be safe?
    this.b = new B();
    this.c = this.b;
  }

}

export function fib(n: i32): i32 {
  let a = new A();
  return 0;
}
Error:
;; ERROR TS2564: Property 'module/A#c' has no initializer and is not assigned in the constructor before 'this' is used or returned.
;;    :
;;  4 │ c: B;
;;    │ ~
;;    └─ in module.ts(4,3)
;;    :
;;  7 │ this.c = this.b;
;;    │          ~~~~~~
;;    └─ in module.ts(7,14)

Activity

  1. dcodeIO commented on Nov 23, 2022

    @dcodeIO
    Member

    This is in fact a relatively strict check atm, but it is intended. Imagine that this.b is a property that executes arbitrary code (accessing this) when accessed, then in that code this.c has not yet been assigned.

    Edit: Makes me realize that this.b = ... before is similar, but doesn't diagnose an error. I guess what we need there is to detect if something is an actual getter or setter, and only then diagnose 🤔

  2. ppppqp commented on Jan 28, 2023

    @ppppqp

    I was tracking this bug for some time and realized it is actually a feature #1349. In brief, the compiler checks if the class is fully initialized before handling a call on this in the constructor. It is indeed a different behavior than Typescript (so a bit confusing), but as mentioned in the above PR, it can be overcome with an assertion.

    class B {}
    class A {
      b: B;
      c!: B; // add assertion
      constructor() {
        this.b = new B();
        this.c = this.b;
      }
    
    }
    
    /** Calculates the n-th Fibonacci number. */
    export function fib(n: i32): i32 {
      let a = new A();
      return 0;
    }

    This compiles just fine.
    A smarter way to handle this is to only check the accessed properties rather than all properties on this. What do you think?

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions