I have the following code:
The condition is the same in both typeguards, but only the second one works. I’d love to understand why?
export class MessageService {
private _iframe?: HTMLIFrameElement;
sendMessage() {
const appLoaded = !!this._iframe?.contentWindow;
// why does this not work?
if (appLoaded) {
this._iframe.contentWindow.postMessage({}, '*'); // ERROR
}
// while this does
if(!!this._iframe?.contentWindow) {
this._iframe.contentWindow.postMessage({}, '*');
}
}
}
Thanks!
>Solution :
Because TypeScript’s flow analysis doesn’t go that far. It doesn’t track the fact that appLoaded
being true
also means that this._iframe?.contentWindow
is also truthy. It’s just a pragmatic limitation of the compiler. In theory, it could do it (until/unless you called a function after the assignment and before using contentWindow
, at which point this._iframe
and or this._iframe.contentWindow
may have changed), but doing that is complex enough that it doesn’t.
You could always do something like this, if you want to avoid repeating the condition:
const wnd = this._iframe?.contentWindow;
// ...
if (wnd) {
wnd.postMessage({}, '*');
}