user8826104
user8826104

Reputation:

What's the correct type for a variable in TypeScript that's initially undefined?

I have a variable we'll call a in this example:

let a;

I only want to assign it a value if it meets one of the requirements in the switch statement:

switch(someOtherVar) {
  case "a": {
    a = "123";
    break;
  }
  case "b": {
    a = "456";
    break;
  }
}

I then want to check if it has a value like so:

if (a) {
  // ...do something
}

This means a can be a string or undefined, and it starts undefined. If I don't declare the type then it throws the following error:

Variable 'a' implicitly has an 'any' type, but a better type may be inferred from usage.ts(7043)

I'm not sure what the correct way to declare the type would be in this instance:

1. let a: string | undefined; // this seems to be the best way
2. let a = undefined; // this declares it as any which I don't want
3: let a: string; // is this correct if it can be undefined?

Upvotes: 2

Views: 2770

Answers (2)

0x4b50
0x4b50

Reputation: 679

Your first suggestion is correct because a can't be any.

You second suggestion still has the type any. You would need to it as follows but that's basically the same as your first suggestion.

let a: string | undefined = undefined;

Your third suggestion will cause problems because the engine does not expect the value to be undefined.

If you know it's a string, you could declare it as empty string and later check the length of the string.

let a: string = "";
if (a.length > 0) {
  // do something...
}

Upvotes: 0

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250386

The correct type is string | undefined. Under srictNullChecks, the type string does not contain the undefined value or the null value. These two values have their own types undefined and null. So to have a variable that is string or undefined using a union is appropriate.

Note that control flow analysis does a pretty good job of inferring the type for your specific use case if the variable is not referenced in a closure

let a = undefined; // any here 

switch(someOtherVar) {
  case "a": {
    a = "123";
    break;
  }
  case "b": {
    a = "456";
    break;
  }
}
// function x() { console.log(a)}; // if referenced in another function you get an error

a; // but the type of a is string | undefined 

Playground Link

Upvotes: 4

Related Questions