类型保护在分配给布尔值时未被识别 – 严格模式

huangapple go评论53阅读模式
英文:

Type guard not being identified when assigned to boolean - strict mode

问题

以下是翻译好的内容:

我有以下的代码:

两个类型保护中的条件相同,但只有第二个起作用。我很想理解为什么?

```typescript
export class MessageService {
  private _iframe?: HTMLIFrameElement;

  sendMessage() {
    const appLoaded = !!this._iframe?.contentWindow;

    // 为什么这个不起作用?
    if (appLoaded) {
        this._iframe.contentWindow.postMessage({}, '*'); // 错误
    }

    // 而这个却可以
    if(!!this._iframe?.contentWindow) {
        this._iframe.contentWindow.postMessage({}, '*');
    }
  }
}

TS Playground 链接

谢谢!


注意:我已经删除了代码部分,只提供了翻译好的文本。

<details>
<summary>英文:</summary>

I have the following code:  

The condition is the same in both typeguards, but only the second one works. I&#39;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({}, &#39;*&#39;); // ERROR
}

// while this does
if(!!this._iframe?.contentWindow) {
    this._iframe.contentWindow.postMessage({}, &#39;*&#39;);
}

}
}


[TS Playground link][1]


Thanks!

  [1]: https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBAYwDYEMDOa4FlgZQc2AGVgoA3ASwWDgG8AoOOMKCslGGgfQoDMoUAW2AB%20AFxwAEgBUsAGQCSAMQHCAokmDCAdjADc9RnDTBtAExx5CACgCUdI0wQRtaeCjBg5EFGeBm4AF44AEIQmAALCjQAOh5%20IVEY511TGAB1CnMIAHcDRzgAekK4HIiATzgzCFw4SOi4bQh4HOgAaxECvjhrDy8fPzN7BiZR0frY%20NVgZJdOXUzsnJjIN0s0AmBrWgBfABo4AHIAKkPbAzGdwzHi0qjNOqjMatwu3mswibi%20aZFZ1IWWWqOWGBTGXymiX%208wyQNyKwga1wGxsuwOJzOF1GVyYVx2QA

</details>


# 答案1
**得分**: 0

因为TypeScript的流分析不会走得那么远。它不会跟踪`appLoaded`为`true`也意味着`this._iframe?.contentWindow`也为真的事实。这只是编译器的实际限制。从理论上讲,它是可以做到的(直到/除非在分配之后并在使用`contentWindow`之前调用函数,此时`this._iframe`和/或`this._iframe.contentWindow`可能已经改变),但这样做足够复杂,以至于不值得。

如果你想避免重复条件,你可以始终像这样做:

```javascript
const wnd = this._iframe?.contentWindow;
// ...
if (wnd) {
    wnd.postMessage({}, '*');
}
英文:

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({}, &#39;*&#39;);
}

huangapple
  • 本文由 发表于 2023年2月14日 20:26:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75447818.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定