reactjs - React with TypeScript - 类型 {...} 不可分配给类型 'Readonly<S>'

标签 reactjs typescript interface

我使用一个抽象类作为父 React 组件,我的应用程序中有许多子组件对此进行了扩展。

它有一个默认状态以及几个类方法,可以选择从扩展组件中覆盖这些方法。

抽象组件如下所示:

import * as React from 'react';

export interface StatefulProps {
  observers?: Array<(context: any, state: object) => any>;
}
export interface StatefulState {
  machine: {
    [propName: string]: any;
  };
  name: string;
  value?: any;
}

export default abstract class StatefulComponent<P extends StatefulProps, S extends StatefulState> extends React.Component<P, S> {
  static defaultProps = {
    observers: [],
  };

  state = {
    machine: {},
    name: '',
  };

  abstract generateState(stateName: string, stateParam?: any): object;

  shouldComponentUpdate(_: P, nextState: S) {
    const { name } = this.state;
    if (nextState && nextState.name !== name) {
      return true;
    }
    return false;
  }

  goToState = (stateName: string, stateParam?: any) => {
    const { observers } = this.props;
    this.setState(
      {
        name: stateName,
        machine: this.generateState(stateName, stateParam),
      },
      () => {
        if (observers && observers.length) {
          observers.forEach(observer => {
            if (observer instanceof Function) {
              observer(this, this.state);
            }
          });
        }
      }
    );
  }
}

但状态由 tslint 加下划线,它在悬停时显示以下错误:

Property 'state' in type 'StatefulComponent<P, S>' is not assignable to the same property in base type 'Component<P, S, any>'.
Type '{ machine: {}; name: string; }' is not assignable to type 'Readonly<S>'.

我一辈子都弄不明白为什么它在提示......

我对 TypeScript 还很陌生,所以完全有可能我在做事的方式上完全是个傀儡,但我将不胜感激任何建议/帮助!

最佳答案

您不能将对象字面量分配给泛型类型的对象。通用类型约束定义了 S 可以拥有的最小属性集,但它可以拥有更多属性,其中一些是强制性的,请考虑这个派生类:

class MyStatefulComponent extends StatefulComponent<StatefulProps, StatefulState & { newMandatoryProp: number }> {
    constructor(p: StatefulProps){
        super(p);
        this.state.newMandatoryProp // will be undefined beacuse the base class did not initailize it correctly 
    }
    generateState(stateName: string, stateParam?: any): object { return null as any }
}

无论如何您都可以使用类型断言来执行此操作,但它不是类型安全的:

export default abstract class StatefulComponent<P extends StatefulProps, S extends StatefulState> extends React.Component<P, S> {
    constructor(props: P) {
        super(props);

        this.state = {
            machine: {},
            name: '',
        } as S;
    }
}

您还可以使用抽象方法来创建状态,并将创建完整状态对象的责任传递给派生类。

关于reactjs - React with TypeScript - 类型 {...} 不可分配给类型 'Readonly<S>',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51651678/

相关文章:

javascript - ReactJS:如何将 Material-UI 的 <DatePicker/> 的占位符和文本居中?

java - Java 8 中接口(interface)和抽象类之间的根本区别

java - 在 Java 中转换接口(interface)

javascript - Yarn 添加 node-sass 失败

javascript - ReactJS:如何在 <div> 内将表单 <Field> 的 &lt;input&gt; 和 <button> 以及 <h1> 对齐?

ruby-on-rails - 将模型传递给组件

检查 null/undefined 的 Typescript 函数

reactjs - 如何将自定义组件传递给 MUI 工具提示中的标题 Prop ?

javascript - ionic 2 : Set interval

c++ - 如何枚举所有可用的网络接口(interface)?