这是一个自我解释的例子:
type TypeX = {t:"a", a1:string} | {t:"b", a2: string};
let t: TypeX | undefined;
function setA(){
t = {t:"a", a1:"values"};
}
setA();
console.log(t.a1);
最后一行符合 TS 要求:
类型“TypeX”上不存在属性“a1”。 类型 '{ t: "b"; 上不存在属性 'a1' a2:字符串; }'。(2339)
除了将
t
转换为 {t:"a", a1:string}
之外,还有其他方法可以告诉 TS,嘿,我知道类型是 {t:"a", a1:string}
,因为 setA
刚刚被调用。
我正在寻找类似的内容,“嘿 TS,当调用函数
setA
时,t
类型是 {t:"a", a1:string}
”。
顺便说一句,我知道我可以像下面这样进行运行时检查,但我正在寻找更多的编译时检查,并且比额外的
if
更聪明:
if(t && t.t === "a"){
console.log(t.a1);
}
TS 进行一些控制流分析,但不进行内联函数调用。
当看到函数调用时,它有局部变量。 请参阅控制流分析中的权衡#9998
首要问题是:当一个函数被调用时,我们应该假设它的副作用是什么?
一种选择是悲观并重置所有缩小范围,假设任何函数都可能会改变它可能接触到的任何对象。另一种选择是乐观并假设该函数不会修改任何状态。这两个好像都不好。
这个问题涉及局部变量(可能会受到一些“封闭与否”分析)和对象字段的影响。