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.
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.