【发布时间】:2019-03-22 10:12:36
【问题描述】:
我已经为 State 定义的 Parent 类创建了一个接口:
interface ParentState { name: string; }
我创建了一个具有上述类型状态的组件:
class Test extends React.Component<{}, ParentState> {
constructor(props: any) {
super(props);
// Works fine!
this.state = { name: '' };
}
}
这是按预期工作的。但是,如果我创建一个父组件和一个子组件,其中子组件从父组件继承,子组件从父组件继承,则父组件的状态变为只读。
interface ChildState extends ParentState {}
class Parent<P, S extends ParentState> extends React.Component<P, S> {
constructor(props: P) {
super(props);
this.state = { name: '' };
^^^^^^^^^^
// Compilation error!
// TS2322: Type '{}' is not assignable to type 'Readonly<S>'.
}
render() {
return <div>parent</div>;
}
}
class Child extends Parent<{}, ChildState> {
constructor(props: ChildProps) {
super(props);
// Works fine!
this.state = { name: '' };
}
render() {
return <div>child</div>;
}
}
谁能解释一下这种行为。
附:
我还有几个问题。
另外,在 React 库中,当我打开 index.d.ts 文件时,state 实际上是 readonly。这在前面提到的 Test 类中是如何工作的?
-
如果我在 Test 类的构造函数中没有提及 props 的类型,则会出现编译错误提示
TS7006: Parameter 'props' implicitly has an 'any' type.为什么不采用类定义中提到的类型
{}?
【问题讨论】:
-
最后一点(#1)很简单:
readonly属性应该在构造函数中被初始化。 -
你有多确定
this.state = {}在Test的情况下没问题,并且不会告诉你“property 'name' is missing in type '{}'”? -
@jcalz 对不起,我的错。我现在已经编辑了这个问题。我的目的是证明 this.state 在 Test 类中仍然是可分配的。但它在 Parent 类中的工作方式不同。
-
#2:因为子类的构造函数不需要看起来像父类的构造函数,所以编译器不知道
props参数必须是什么类型。
标签: reactjs typescript generics inheritance covariance