Reputation: 2321
I have a Typescript interface representing a user query. As such, it contains mostly optional fields:
interface InputData {
fieldOne?: {
requiredField: {
key: string;
values?: string[];
}
}
fieldTwo?: {
etc?: string;
}
}
Using the --strictNullChecks
flag with Typescript, I have to make sure that each property is not undefined before accessing it:
function do_something(input: InputData): void {
const messages: string[] = [];
if (input.fieldOne !== undefined) {
if (input.fieldOne.requiredField.values !== undefined) {
console.log(input.fieldOne.requiredField.values):
// no errors
}
}
}
However, if I try and use an optional field inside of a forEach
or map
, even after checking if it is undefined, I recieve an error:
if (input.fieldOne !== undefined) {
if (input.fieldOne.requiredField.values !== undefined) {
input.fieldOne.requiredField.values.forEach(v => {
messages.push(`${v} ${input.fieldOne.requiredField.key}`);
// error!
});
}
}
"input.fieldOne" | Object is possibly undefined. (2532)
Here it seems like Typescript is "losing" the context that this field is not undefined inside of the forEach
or map
call.
How can I fix this error? Is there a better way to handle these undefined fields? Thanks!
(Here is a link to this error in the Typescript Playground.)
Upvotes: 3
Views: 818
Reputation: 9377
Use the Non-Null
assertion operator (!
). You'll be telling typescript compiler: "Trust me, I know what I'm doing."
console.log(input.fieldOne!.requiredField.values):
Another approach would be creating another variable before the forEach
statement, where typescript compiler still trust on if
scope:
if (input.fieldOne) {
const requiredField = input.fieldOne.requiredField;
requiredField.values.forEach(v => messages.push(`${v} ${requiredField.key}`));
}
A third approach would be retesting input.fieldOne
inside the forEach
loop. It would cause a performance decrease though:
if (input.fieldOne) {
input.fieldOne.requiredField.values.forEach(v => {
if (input.fieldOne) {
messages.push(`${v} ${input.fieldOne.requiredField.key}`);
}
});
}
Upvotes: 1