aryzing
aryzing

Reputation: 5867

Yet another "Object is possibly 'undefined'", but it really can't be

TS is reporting a classic "Object is possibly 'undefined'" error with the below code, yet it is impossible for the value to be undefined. What is causing this error to be reported? A link to the docs where this behavior is described would be great!

const maybeTrue = Math.random() < 0.5;

let myStr;

if (maybeTrue) {
  myStr = 'abc';
}

if (maybeTrue) {
  console.log(myStr.toLowerCase()); // Error here, `myStr` possibly undefined
}

Playground link

Upvotes: 1

Views: 86

Answers (2)

davidmpaz
davidmpaz

Reputation: 1387

As is see in the playground script. The reported error is clear in the way that let declare the variable but it is not initialized, so it is undefined.

Then the string type is inferred from your assignment inside the conditional sentence.

I don't believe typescript compiler can infer that in the second conditional the variable is initialized and is a string. I have seen some GitHub issues related to this, I can not find any to link unfortunately.

But we can test it somehow, in the playground you provided:

  • If we initialize the variable to empty string, the error disappear.
const maybeTrue = Math.random() < 0.5

let myStr = ""
if (maybeTrue) {
  myStr = 'abc'
}

if (maybeTrue) {
  console.log(myStr.toLowerCase())
}
  • If we move the console.log sentence to first if, the error is not reported.
const maybeTrue = Math.random() < 0.5

let myStr = ""
if (maybeTrue) {
  myStr = 'abc'
  console.log(myStr.toLowerCase())
}

Take a look here: https://www.typescriptlang.org/docs/handbook/type-inference.html and here https://www.typescriptlang.org/docs/handbook/advanced-types.html for more detailed information about how types are implemented

Upvotes: 0

axiac
axiac

Reputation: 72226

The TypeScript compiler does a static analysis of the code. This analysis reveals that the statement that reads the value of myStr can be reached through a code path that initializes myStr (when the condition of the first if is true) or a code path that skips the initialization.

The compiler does not run the code, it does not evaluate the conditions, it does not "notice" that both if statements use the same condition.

For the analysis both ifs look like if (<condition>) { <statements> }. All it matters for it is that <statements> are not executed on all code paths, therefore after the first if statement myStr might be or might not be initialized.

Upvotes: 1

Related Questions