我将此代码视为将空状态定义为空,但是当我编写此代码时,没有任何错误。
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,我该如何设置它?
在我看到这个问题时,需要进行一些挖掘以找出主要问题:为什么TypeScript允许您将具有属性的对象分配给声明为空对象的属性?
答案似乎被埋没在TypeScript spec a bit中
实际上,类型的明显成员使其成为“对象”或“函数”接口的子类型,除非该类型定义与“对象”或“函数”接口的成员不兼容的成员。
也就是说,{}
的处理方式与Object
相同。这允许您创建一个具有{}
类型的附加属性的对象,这正是您正在做的事情。请注意,不应该允许this.state.foo
,因为foo
上不存在{}
属性。同样,你也无法做this.state.foo =
。
至于为什么你可以将具有未知属性的对象传递给Object
或setState
,这与TypeScript的类型兼容性有关。请参阅:https://www.typescriptlang.org/docs/handbook/interfaces.html进行一种解释
请注意,我们的对象实际上具有比此更多的属性,但编译器仅检查至少存在所需的属性并匹配所需的类型。
这也解释了:
对象文字在将它们分配给其他变量或将它们作为参数传递时,会得到特殊处理并进行多余的属性检查。
因此,你的问题的答案似乎是你在这里使用{}
,TypeScript正在对待它,好像你正在使用不是对象文字类型的Object
。
我不确定你将如何强制执行没有属性的状态,但另一方面,我不确定这将如何有用。如果您想要一个没有属性的组件,请使用无状态或功能组件。