'Cannot invoke an object which is possibly 'undefined' when not using an intermediate const
I have this code:
const someCallBack = (message : string)=>{
console.log(message)
}
type MyType = {
who : string,
callback? : (message : string)=>void,
}
// Some function to get a
const getObj = () : MyType =>{
return {
who : "Carol"
};
};
const x = getObj();
if(x.callback){
x.callback("x");
}
const data : MyType[] = [
{ who:"Alice" },
{ who:"Bob", callback:someCallBack }
];
// No intermediate const
for(let i=0; i<data.length;i++){
console.log(data[i].who);
if(data[i].callback) {
data[i].callback(data[i] + " callback");
}
}
// intermediate const for the object
for(let i=0; i<data.length;i++){
const myObj = data[i];
console.log(myObj.who);
const callback = myObj.callback;
if(callback) {
callback(myObj + " callback");
}
}
// intermediate const for the callback
for(let i=0; i<data.length;i++){
console.log(data[i].who);
const callback = data[i].callback;
if(callback) {
callback(data[i] + " callback");
}
}
It fails to compile in the first attempt to loop : Cannot invoke an object which is possibly 'undefined'.
But as soon as I introduce a local for either the object from the loop, or the callback itself, it compiles (2nd and 3rd loops).
The question is : why? What's the difference?
Here's the TS playground export:
Output"use strict";
const someCallBack = (message) => {
console.log(message);
};
// Some function to get a
const getObj = () => {
return {
who: "Carol"
};
};
const x = getObj();
if (x.callback) {
x.callback("x");
}
const data = [
{ who: "Alice" },
{ who: "Bob", callback: someCallBack }
];
// No intermediate const
for (let i = 0; i < data.length; i++) {
console.log(data[i].who);
if (data[i].callback) {
data[i].callback(data[i] + " callback");
}
}
// intermediate const for the object
for (let i = 0; i < data.length; i++) {
const myObj = data[i];
console.log(myObj.who);
const callback = myObj.callback;
if (callback) {
callback(myObj + " callback");
}
}
// intermediate const for the callback
for (let i = 0; i < data.length; i++) {
console.log(data[i].who);
const callback = data[i].callback;
if (callback) {
callback(data[i] + " callback");
}
}
Compiler Options
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES2017",
"jsx": "react",
"module": "ESNext",
"moduleResolution": "node"
}
}
Playground Link: Provided
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
