为什么super()无法在不变记录上设置?

时间:2019-06-19 13:47:00

标签: reactjs typescript redux create-react-app immutable.js

我正在设置一个非常简单的新Redux存储状态。

我已经“克隆”了我之前创建的Redux存储,并对其进行了简化。 我首先尝试只在一种状态下进行,reducer,selector和action,然后尝试创建一棵树(如我的旧项目),但没有任何改变。我检查了package.json,发现我有相同的Redux,React,ReactRedux,Typescript,ecc ...版本。

import { Record } from "immutable";

export enum officeLocations {
    cityOne = "CITYONE",
    cityTwo = "CITYTWO",
    none = "NONE",
    cityThree = "CITYTHREE",
    cityFour = "CITYFOUR"
}

export interface ILocationInfo {
    location: officeLocations;
}

const LocationInfoRecord = Record({
    location: officeLocations.none
});

export class LocationInfo extends LocationInfoRecord implements ILocationInfo {
    public location: officeLocations;

    constructor(props?: ILocationInfo) {
        // props ? super(props) : super(); <-- in older project I use this line instead of if-else... but here it tell me I cannot invoke super multiple times...
        if (props) {super(props);}
        else {super();}
        this.location = props ? props.location : officeLocations.none; // <- In my older code I don't need this line, for some reason it give me an error that location is not instantiated if I don't put this line
    }

    public with(values: Partial<ILocationInfo>) {
      return this.merge(values);
    }
}

我希望它可以正常工作...但是Typescript不会给我带来任何问题并进行编译,但是在“ super()”上运行它时崩溃,提示“错误:无法在不可变的记录上设置”。

**

更新:

**

今天,在不进行任何更改的情况下,会出现此错误:

  

类型'(位置:LocationInfo,操作:IAction)=>地图'   不可分配给“ Reducer,any>”类型。种类   参数“ LocationInfo”和“状态”不兼容。       输入“地图|未定义”无法分配给“ LocationInfo”类型。         类型'undefined'不能分配给类型'LocationInfo'

现在,即使是我的原始代码,它也会给我这个错误,其中包含代码注释。

当我称“ combineReducers”时,会出现此错误。

    const settingsReducer = combineReducers({
       location: locationReducer,
       other: otherReducer
    });

1 个答案:

答案 0 :(得分:0)

Record是一个工厂,它产生不可变的记录。 您的代码尝试分配工厂本身的位置,而不是工厂的输出。

  

记录类型比典型的JavaScript更受限制   类。它们不使用类构造函数,这也意味着它们   无法使用类属性(因为从技术上讲,这些属性是   构造函数)。

     

虽然可以使用JavaScript在语法上创建记录类型   类形式,结果Record函数实际上是一个工厂   函数,而不是类构造函数。

TypeScript不能很好地处理Immutable。两者都希望对结构进行明确的定义,但是它们需要在另一个层次上并以另一种方式进行,从而使您编写了冗余代码。

因此location属性仅出于TS的考虑,并未真正使用。我们不应尝试为其分配任何内容,只需告诉TS,它已被神奇分配:

public readonly location!: officeLocations

然后删除this.location = props ? props.location : officeLocations.none;

如果您出于某种原因想要更改输入,只需在构造函数中进行操作,然后将所有内容传递给super:

constructor(values = {}, name) {
    values.location = values.location || officeLocations.none;
    super(values, name);
}

Here is an article并说明如何在TypeScript中使用不可变记录。