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

问题描述 投票:5回答:1

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

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

这也不是错误:

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

我在这里显然不了解TypeScript。如果我向传递的状态对象添加一个参数,则两个错误都显示状态差异。似乎{}没有提供任何防止被覆盖的警惕。我想从lint的角度确保状态总是被输入并作为参数传递或在React Component的扩展中作为null,我该如何设置它?

reactjs typescript ecmascript-6 state
1个回答
2
投票

在我看到这个问题时,需要进行一些挖掘以找出主要问题:为什么TypeScript允许您将具有属性的对象分配给声明为空对象的属性?

答案似乎被埋没在TypeScript spec a bit

实际上,类型的明显成员使其成为“对象”或“函数”接口的子类型,除非该类型定义与“对象”或“函数”接口的成员不兼容的成员。

也就是说,{}的处理方式与Object相同。这允许您创建一个具有{}类型的附加属性的对象,这正是您正在做的事情。请注意,不应该允许this.state.foo,因为foo上不存在{}属性。同样,你也无法做this.state.foo =

至于为什么你可以将具有未知属性的对象传递给ObjectsetState,这与TypeScript的类型兼容性有关。请参阅:https://www.typescriptlang.org/docs/handbook/interfaces.html进行一种解释

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

这也解释了:

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

因此,你的问题的答案似乎是你在这里使用{},TypeScript正在对待它,好像你正在使用不是对象文字类型的Object

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

© www.soinside.com 2019 - 2024. All rights reserved.