这是React + Typescript问题。 我有一个使用道具和状态的两个泛型的组件。
interface Props {
foo: string;
}
interface State {
bar: string;
}
class Foo<
P extends Props = Props,
S extends State = State
> extends React.Component<P, S> {
constructor(props: P) {
super(props);
this.state = { bar: "asd" };
}
}
发现在构造函数中对this.state
的配属是错误消息:
输入'{bar:“ asd”; }”不可分配为“ Readonly(S)”类型
当您从类声明中删除泛型并将State
接口直接传递给React.Component<P, State>
时,一切正常。
我的问题是如何避免这种错误?我需要以一种可以验证已知状态参数(例如本例中的bar)但允许指定其他属性的方式来初始化状态。
答案 0 :(得分:1)
您尝试初始化通用类型,这是错误的,因为您可以扩展此类型并且初始化将不正确
示例:
const instance = new Foo<Props, { otherRequiredProperty: string } & State>({ foo: '' });
cosnt otherProperty = instance.state.otherRequiredProperty
所以我说状态类型将具有2个必需的道具,但是在您的班级中,您仅用bar进行了初始化...
您可以根据需要创建带有所需道具和其他可选道具的界面
interface Props {
foo: string;
}
interface State {
bar: string;
[key: string]: string;
}
export class Foo extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
bar: '',
};
this.setState({
anything: '', // no error
});
}
}
这不会引发错误,您仍然可以在状态中添加另一个属性
答案 1 :(得分:0)
尝试一下:
class Foo extends React.PureComponent<P, S> {
state: State; //Add this line
constructor(props: P) {
super(props);
this.state = { bar: "asd" };
}
}
答案 2 :(得分:0)
@Juraj Kocan在他的回答中写道。造成此问题的原因是:
您尝试初始化通用类型,这是错误的,因为您可以扩展此类型并且初始化将不正确
与此同时,我发现我可以通过在构造函数中扩展状态来处理它:
interface Props {
foo: string;
}
interface State {
bar: string;
}
class Foo<
P extends Props = Props,
S extends State = State
> extends React.Component<P, S> {
constructor(props: P) {
super(props);
this.state = { ...this.state, bar: "asd" };
}
}
您也可以在没有构造函数的情况下执行此操作:
interface Props {
foo: string;
}
interface State {
bar: string;
}
class Foo<
P extends Props = Props,
S extends State = State
> extends React.Component<P, S> {
state:S = { ...this.state, bar: "asd" };
}
后一种解决方案更好,因为在构造函数中传播this.state会使我使用immutability-helper的地方出现其他错误。在构造函数中的传播使TypeScript在immutability-helper的update()函数中无法跟踪索引属性。