Search code examples
typescriptundefinedflags

How should I link load flags to their data in typescript


I have a started flag, and then other data about the progress of some action.

let started: boolean = false;
let foo: number|undefined = undefined;
let bar: string|undefined = undefined;

Any other data is undefined until the action starts.
If I have a function that mutates this state, then typescript warns me that foo may be undefined, as I haven't explicitly linked it to started.

function mutate() {
  if (!started) return;
  foo++;
  bar = "qaax";
}

Is there a way to tell typescript that foo and bar are only undefined when started is false, and if not then what is the best way to handle sitautions like this where the existence of data is dependent on the value of some other data?

Potential solutions:

  • I could use -1 instead of undefined, but that is less readable and sometimes -1 will be used by the data.

  • Alternatively I could check individually that foo and bar are not undefined, but this becomes extemely ineficient with more complex data.

  • Since whether the action has started is tracked seperately, I could leave foo and bar with any values as once the action starts then their values will be reset to meaningful ones. However again this would be much less readable.


Solution

  • The typechecker cannot infer from the runtime state that whether a variable is undefined or not. In your case use the non null assertion operator "!" to assert that "foo" will never be undefined when "started = true". This will lead to runtime error when "foo" is undefined.

    foo!++;

    The optional chaining operator "?" is introduced to optionally check whether a property is in an object or not to reduce the boilerplate code as described here https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining. This is just a shorthand for manually checking whether "foo.some" is undefined or not. This will not cause runtime errors.