首页 > 解决方案 > 为什么将类型声明为联合与可选时,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
  });
}

从人类的角度来看,上述两个函数(remove1remove2)具有完全相同的含义,而打字稿则对其进行了不同的处理。这对我来说没有意义,这就是我的推理方式

对于remove1(1)之后,ts知道id肯定存在,所以document.getElementById(dialog.id)是OK的,因为它在同一个事件循环中,但是细化没有进行到新的范围(setTimeout)。这种行为对我来说很有意义,dialog.id由于事件循环,检查后仍然会发生变化

但是,对于remove2,并没有 ts 错误,因为对setTimeout. 这种行为实际上是错误的,即运行时错误

实际上,我不能自信地理解 typescript 是如何看待代码的,任何人都可以通过它或向我指出一些相关的材料,特别是关于 typescript 的改进和范围。

标签: typescripttypesscoperefinement-type

解决方案


推荐阅读