Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uninitialized instance properties can be accessed via initializers #57984

Closed
igrep opened this issue Mar 28, 2024 · 2 comments
Closed

Uninitialized instance properties can be accessed via initializers #57984

igrep opened this issue Mar 28, 2024 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@igrep
Copy link

igrep commented Mar 28, 2024

πŸ”Ž Search Terms

  • "constructor instance variable undefined"
  • "instance property undefined constructor uninitialized"

πŸ•— Version & Regression Information

> npx tsc --version
Version 5.4.3

⏯ Playground Link

https://www.typescriptlang.org/play?noUncheckedIndexedAccess=true&ts=5.5.0-dev.20240328#code/MYGwhgzhAECiAeYC2AHEBTaBvAUNaYAXNBAC4BOAlgHYDmA3HtAEbQC80pAFpRAHQBXCOgCCACgCUjfMAD21MuQHBSs8mKIkKNWhOxN83XnzDsC06AF8cTIaMnFFO-fnzl0pAeWqce-MHyqAKooKOjkAMKQ6JIW1tY4cgqyGHwgsrRi1OgA7nCIqBhiAOToBWjoxRJ8zFJAA

πŸ’» Code

tsconfig.json:

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true
  }
}

example.ts:

class Example {
  a: string;
  b = this.useA();
  constructor(a: string) {
    this.a = a;
  }

  useA(): string {
    return this.a.toUpperCase();
  }
}

console.log(new Example('example').b);

πŸ™ Actual behavior

Produces no compile error, and generates a code that throws a runtime error:

TypeError: Cannot read properties of undefined (reading 'toUpperCase')

πŸ™‚ Expected behavior

Produces a compile error similar to "Property 'a' is used before its initialization."

Additional information about the issue

I'm not sure whether this may be a issue that can be fixed or just keep it as is "by design". I haven't found any other issues similar to this one here, at least with the search terms I tried.

As you know, we can easily modify the example case like below to avoid the error:

class Example {
  b = this.a;
  constructor(public a: string) {
    this.a = a;
  }

  useA(): string {
    return this.a.toUpperCase();
  }
}

console.log(new Example('example').b);

But we can't adopt this workaround when the property is a hard-private one:

class Example {
  #privA: string;
  #privB = this.useA();
  constructor(privA: string) {
    this.#privA = privA;
  }

  useA(): string {
    return this.#privA.toUpperCase();
  }

  get a(): string {
    return this.#privA;
  }

  get b(): string {
    return this.#privB;
  }
}

console.log(new Example('example').b);

Actually I found this problem when using a hard-private variable.

@MartinJohns
Copy link
Contributor

Duplicate of #38205 / #11006.

@igrep
Copy link
Author

igrep commented Mar 28, 2024

Sorry. I failed to search the existing issues well.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Mar 28, 2024
@igrep igrep closed this as completed Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants