为什么在正确识别对象类型之前需要强制枚举值?

时间:2019-04-01 15:47:36

标签: typescript enums

我有一个在type属性上有区别的对象,该属性可以是给定枚举的任何值。当我创建一个有效的对象然后将其传递给函数时,打字稿会抱怨类型不匹配。但是,如果我强制使用枚举值,那就没问题了。

enum AorB {
  A = 'a',
  B = 'b',
};

type Bar_A = {
  type: AorB.A;
};

type Bar_B = {
  type: AorB.B;
}

type Bar = Bar_A | Bar_B;

function foo(a: Bar): void {}

const arg = {
  type: AorB.A,
};

// this would work but is extra writing
// const arg = {
//   type: AorB.A as AorB.A
// };

foo(arg); // Error
foo({
  type: AorB.A,
})

请参阅等效的playground link

1 个答案:

答案 0 :(得分:2)

Typescript会加宽文字类型,除非有理由保持它们不变,所以arg的类型应为{type: AorB }而不是{ type: AorB.A, }

如果您明确使用类型断言AorB.A as AorB.A,则打字稿将保留文字类型。如果将对象文字分配给需要Bar的位置(例如函数的参数),则文字脚本将再次保留文字类型。

另一个可行的方法是显式键入arg

const arg: Bar = {
  type: AorB.A,
};

foo(arg);
foo({
  type: AorB.A,
})

或者在3.4中使用as const来使编译器保留文字类型,而不必再次指定类型,尽管这会使整个对象变为只读。