typescript - 为什么将类型声明为联合与可选时,TypeScript 细化的工作方式不同?
问题描述
type Dialog1 = { id?: string };
type VisibleDialog = { id: string };
type DestroyedDialog = {};
type Dialog2 = VisibleDialog | DestroyedDialog;
function remove1(dialog: Dialog1) {
if (!dialog.id) {
return;
}
//(1)
document.getElementById(dialog.id); //dialog:Dislog1
setTimeout(() => {
//Argument of type 'string | undefined' is not
//assignable to parameter of type 'string'.
document.getElementById(dialog.id);
});
}
function remove2(dialog: Dialog2) {
if (!("id" in dialog)) {
return;
}
document.getElementById(dialog.id); //dialog:VisibleDialog
setTimeout(() => {
document.getElementById(dialog.id); //dialog:VisibleDialog
});
}
从人类的角度来看,上述两个函数(remove1
和remove2
)具有完全相同的含义,而打字稿则对其进行了不同的处理。这对我来说没有意义,这就是我的推理方式
对于remove1
(1)之后,ts知道id
肯定存在,所以document.getElementById(dialog.id)
是OK的,因为它在同一个事件循环中,但是细化没有进行到新的范围(setTimeout
)。这种行为对我来说很有意义,dialog.id
由于事件循环,检查后仍然会发生变化
但是,对于remove2
,并没有 ts 错误,因为对setTimeout
. 这种行为实际上是错误的,即运行时错误
实际上,我不能自信地理解 typescript 是如何看待代码的,任何人都可以通过它或向我指出一些相关的材料,特别是关于 typescript 的改进和范围。
解决方案
推荐阅读
- android - 车辆行驶时 Android 指南针不工作
- java - 用于 javax.validation.ConstraintViolationException 的 Dropwizard 自定义 ExceptionMapper
- reactjs - 可能未处理的 Promise Rejection (id: 0): [Answer] React Native Error while making XMLHttpRequest via device or emulator
- azure - 从 cosmos DB 中提取分区键
- ios - RxSwift:链 Completable 到 Observable
- spring - 使用任何字段分隔符处理文本文件
- git - Jenkins - 如何将变量传递给 Bitbucket 状态通知插件?
- cakephp - 如何在 Cakephp3 的 bootstrp.php 文件中读取会话变量
- android - 如何在 Android 中从一个片段转移到另一个片段
- php - 获取php中关联数组的最大值