Typescript区分并集,带有泛型、不健全的类型收缩

Typescript区分并集,带有泛型、不健全的类型收缩,typescript,generics,Typescript,Generics,下面的代码使用Typescript 3.5.3成功编译,但似乎不应该允许这样做,我想知道为什么它会成功编译。我创建了一个类型a,它有一个字段a和一个在X上参数化的泛型函数t,该函数接受一个参数,该参数是泛型X和类型a的区别并集。函数t内部a保护中的'a'似乎将a的类型缩小为a,但是,您可以想象另一种类型B,具有不同字段a,可以通过此检查 type A = {"a": string} type B = {"a": number} function t<X>(a: A | X, f:

下面的代码使用Typescript 3.5.3成功编译,但似乎不应该允许这样做,我想知道为什么它会成功编译。我创建了一个类型
a
,它有一个字段
a
和一个在
X
上参数化的泛型函数
t
,该函数接受一个参数,该参数是泛型
X
和类型
a
的区别并集。函数
t
内部a保护中的
'a'似乎将
a
的类型缩小为
a
,但是,您可以想象另一种类型
B
,具有不同字段
a
,可以通过此检查

type A = {"a": string}
type B = {"a": number}

function t<X>(a: A | X, f: (x:X) => string): string {
  if ('a' in a) {
    return a.a;
  } else {
    return f (a);
  }
}

我知道Typescript的类型系统是故意不健全的,但我不明白为什么这个例子被允许是不健全的。如果您有任何见解,我们将不胜感激。

type guard中的
,通常情况下是相当不可靠的。。它很有用,但很容易让运行时错误发生
let a : A = {"a": "hi"};
let f = (x:B) => {
  return x.a + " a string";
}
let tmpa = t(a, f); // has static type string and correct dynamic type string
let b: B = {"a": 5};
let tmpb = t(b, f); // has static type string but dynamic type number