联合类型不能用作“多种类型之一”

时间:2019-12-03 18:32:19

标签: typescript

  

A union type describes a value that can be one of several types.

我想定义A和B类型的类型联合。据我从文档了解,结果类型应该是代表A或B类型的类型。令人惊讶的是,我可以同时使用paramA类型的paramBUnitedAB。为什么会发生这种情况,以及如何创建将返回type A or type B结果的类型?

type A = {
  paramA: any;
};

type B = {
  paramB: any;
};

type UnitedAB = A | B;

const a: UnitedAB = { paramA: 1, paramB: 2 }; //OK (WHY?)
const b: UnitedAB = { paramA: 1}; //ok
const c: UnitedAB = { param12: 1}; //error

1 个答案:

答案 0 :(得分:2)

这里的重要部分稍后在documentation

  

联盟类型在这里可能会有些棘手,但是这需要一点直觉来习惯。 如果值的类型为A | B,我们只能肯定地知道它具有A和B都具有的成员。在此示例中,Bird有一个名为fly的成员。我们无法确定变量类型为Bird |鱼有飞蝇的方法。如果变量在运行时确实是Fish,则调用pet.fly()将失败。

通常,您会有意识地拥有一个AB并将其分配给接受A | B的属性或参数,但是 还有一些方法可以该代码,以便以后知道或辨别它实际上是AB中的哪个。

文档的下一部分Type Guards and Differentiating Types介绍了执行此操作的方法。

这里是一个例子:

class A {
  type = 'A';
  paramA: any;
};

class B {
  type = 'B';
  paramB: any;
};

type UnitedAB = A | B;
function isA(aOrB: A | B): aOrB is A {
  return aOrB.type === 'A';
}

function isB(aOrB: A | B): aOrB is B {
  return aOrB.type === 'B';
}

const a = new A();

function takesAOrB(aOrB: A | B): void {
  if (isA(aOrB)) {
    console.log(aOrB.paramA);
  } else if (isB(aOrB)) {
    console.log(aOrB.paramB);
  }
}

Typescript Playground