小编典典

允许打字稿编译器仅在一个反应​​状态属性上调用setState

reactjs

我正在将Typescript与React一起用于项目。主组件通过此接口获得通过状态。

interface MainState {
  todos: Todo[];
  hungry: Boolean;
  editorState: EditorState;  //this is from Facebook's draft js
}

但是,下面的代码(仅摘录)不会编译。

class Main extends React.Component<MainProps, MainState> {
  constructor(props) {
    super(props);
    this.state = { todos: [], hungry: true, editorState: EditorState.createEmpty() };
  }
  onChange(editorState: EditorState) {
    this.setState({
      editorState: editorState
    });
  }
}

编译器抱怨说,在onChange我仅尝试为一个属性设置状态的方法中,该属性todos和该属性hungry在type中丢失{ editorState: EditorState;}。换句话说,我需要在onChange函数中设置所有三个属性的状态,以使代码得以编译。为了使其编译,我需要做

onChange(editorState: EditorState){
  this.setState({
    todos: [],
    hungry: false,
    editorState: editorState
  });
}

但目前没有理由在代码中设置todoshungry属性。在打字稿/反应中仅对一个属性调用setState的正确方法是什么?


阅读 277

收藏
2020-07-22

共1个答案

小编典典

编辑

react的定义已更新,其签名setState现在为:

setState<K extends keyof S>(state: Pick<S, K>, callback?: () => any): void;

Pick<S, K>被内置其中在打字稿2.1添加类型:

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}

有关更多信息,请参见映射类型
如果仍然存在此错误,则可能需要考虑更新您的反应定义。

原始答案:

我正面临着同样的事情。

我设法解决这个烦人的问题的两种方法是:

(1)投射/断言:

this.setState({
    editorState: editorState
} as MainState);

(2)将接口字段声明为可选:

interface MainState {
    todos?: Todo[];
    hungry?: Boolean;
    editorState?: EditorState;
}

如果有人有更好的解决方案,我将很高兴知道!


编辑

虽然这仍然是一个问题,但是有两个关于将解决此问题的新功能的讨论:
部分类型(现有类型的可选属性)
以及
Object.assign和React组件setState()的更准确键入

2020-07-22