为什么打字稿允许我覆盖一个空状态对象?

时间:2019-02-20 15:36:04

标签: reactjs typescript ecmascript-6 state

我阅读此代码以将状态定义为空,但是当我编写此代码时,没有任何错误。

export default class extends Component<Props, {}> {
  state = {
    foo: "bar"
  };
}

这也不出错:

export default class extends Component<Props, {}> {
  constructor(props) {
    super(props);
    this.setState({ foo: "bar" });
  }

我在这里显然不了解有关TypeScript的某些知识。如果我将一个参数添加到所传递的状态对象,则两个错误都将显示状态差异。 {}似乎没有提供任何防止被覆盖的保护措施。我想从linting的角度确保状态始终是类型化的,并在React Component的扩展名中作为参数或null传递,我该如何设置呢?

1 个答案:

答案 0 :(得分:2)

这需要花点时间找出我所看到的主要问题:为什么TypeScript允许您将具有属性的对象分配给声明为空对象的属性?

答案似乎藏在TypeScript spec a bit

  

实际上,类型的外观成员使其成为“对象”或“功能”接口的子类型,除非该类型定义的成员与“对象”或“功能”接口的成员不兼容。

也就是说,出于类型目的,{}Object相同。这使您可以创建具有{}类型的其他属性的对象。请注意,{<1>}不应 ,因为属性this.state.foofoo上不存在。同样,您将无法执行{}

关于为什么可以将具有未知属性的对象传递给this.state.foo =Object的原因,这与TypeScript的类型兼容性有关。参见:https://www.typescriptlang.org/docs/handbook/interfaces.html以获得一种解释

  

请注意,我们的对象实际上具有比此更多的属性,但是编译器仅检查至少存在所需的属性并匹配所需的类型。

这也可以解释:

  将对象文字分配给其他变量或将其作为参数传递时,对对象文字进行特殊处理并进行多余的属性检查

因此,您的问题的答案似乎是您在此处使用setState的地方,TypeScript将其视为您正在使用{em> not 的{}对象文字类型。

我不确定您将如何强制执行没有属性的状态,但是另一方面,我不确定这将如何有用。如果要使用没有属性的组件,请使用无状态或功能组件。