首页 > 解决方案 > 为什么编译器隐式类型转换不适用于作为扩展接口实现的文字类型属性?

问题描述

为什么编译器隐式类型转换不适用于作为扩展接口实现的文字类型属性?

例子:

// typescript 3.4.5

interface INumContainer {
  num?: 1 | 2;
}

class myClass implements INumContainer {
  // does not compile
  // error TS2416: Property 'num' in type 'myClass' is not assignable to the same property in base type 'INumContainer'.
  //   Type 'number' is not assignable to type '1 | 2 | undefined'.
  num = 1;

  anotherNum: 1 | 2 = 1; // compiles
}

标签: typescript

解决方案


至少在 TS3.7 中,类成员不是由它们被声明扩展或实现的类型进行上下文类型化的。extendsorimplements声明确实会导致扩展/实现类的类型检查但这会在以后发生。长期以来,这一直是一个痛点。

这里发生的是文字类型 like12被扩展为包含类型 like number除非它们处于非扩展上下文中。并且由于myClass.num不是由 上下文键入的INumContainer["num"],因此它被扩展为number,这被认为是不兼容的。

关于属性的原始问题是microsoft/TypeScript#3667曾尝试修复它,但由于与某些实际代码库的互操作性较差,最终被拒绝/放弃。

从那以后并没有发生太多事情。目前关于这个主题的开放问题似乎是microsoft/TypeScript#32082,所以如果你想看到这个问题得到解决,你可能想去那个问题并给它一个或其他的支持。

在那之前,你只需要对你的初始化器进行冗余注释。对不起,我没有更好的答案给你。希望有帮助;祝你好运!


推荐阅读