我尝试使用reducer设置state.case.summaries.get(action.summary.id).metadata.summaryRank
的值。 summaries
为Immutable.Map<string, Summary>;
我试过这个:
return {
...state,
'case' : {
...state.case,
summaries : {
...state.case.summaries,
[action.summary.id] : {
...state.case.summaries.get(action.summary.id),
metadata : {
...state.case.summaries.get(action.summary.id).metadata,
summaryRank : action.newRank
}
}
}
}
};
但我失去了我的类型:
`state` before:
ApplicationState {_map: Map, __ownerID: undefined}
after:
{_map: Map, __ownerID: undefined, case: {…}}
`case` before:
Case {_map: Map, __ownerID: undefined}
after:
{_map: Map, __ownerID: undefined, summaries: {…}}
`summaries` before
Map {size: 44, _root: HashArrayMapNode, __ownerID: undefined, __hash: undefined, __altered: false}
after
{size: 44, _root: HashArrayMapNode, __ownerID: undefined, __hash: undefined, __altered: false, …}
所以,如果我稍后尝试summaries.get(summaryId)
,我最终会applicationState.case.summaries.get is not a function
然后我尝试过这样做:
return state.set('case',
state.case.set('summaries',
state.case.summaries.get(action.summary.id).set(//not sure what to do here
state.case.summaries.get(action.summary.id).set('metadata',
state.case.summaries.get(action.summary.id).metadata.set('summaryRank',
action.newRank
)
)
)
)
);
但我得到了:
[exec]
[exec] 46 state.case.summaries.get(action.summary.id).set(
[exec] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[exec] 47 state.case.summaries.get(action.summary.id).set('metadata',
[exec] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[exec] ...
[exec] 51 )
[exec] ~~~~~~~~~~~~~~~~~~~~~~~~~
[exec] 52 )
[exec] ~~~~~~~~~~~~~~~~~~~~~
[exec]
[exec] .../services/store/caseReducer.ts(46,21): error TS2346: Supplied parameters do not match any signature of call target.
[exec]
更多信息
case.ts
const CaseRecord = Immutable.Record({
id: '',
reserved:false,
loaded: false,
summaries: Immutable.Map<string, Summary>(),
caseMetadata: new models.CaseMetadata(),
});
export class Case extends CaseRecord {
public id: string;
public loaded: boolean;
public reserved: boolean;
public summaries: Immutable.Map<string, Summary>;
public caseMetadata: models.CaseMetadata;
constructor(properties?: any) {
super(properties);
}
public asMutable(): Case {
let record = <Case>super.asMutable();
record.summaries = this.summaries.asMutable();
this.summaries.forEach((summary) => {
record.summaries = record.summaries.set(summary.id, <models.Summary>summary.asMutable());
});
record.caseMetadata = this.caseMetadata.asMutable();
return record;
}
}
applicationState.ts
const ApplicationStateRecord = Immutable.Record({
case: new models.Case(),
lookupValues: {}
});
export class ApplicationState extends ApplicationStateRecord {
public case: models.Case;
public lookupValues: LookupValues;
constructor(properties?: any) {
super(properties);
}
}
答案 0 :(得分:2)
小心使用redux商店中的类类型 - 你必须确保你没有使用普通的JS对象。
当您执行以下操作时:
return { /* stuff */ }
还没有办法让redux能够告诉你是从另一种类型中推出它。您可以将原始原型应用于:
return Object.assign(new ApplicationState(), { /* stuff */ })
然而,当有很多嵌套时,这是非常繁琐的。
谢天谢地,似乎你一直在使用Immutable的东西,这使得更新嵌套类型变得相当容易。我相信你可以做到:return state.setIn(
['case', 'summaries', action.summary.id, 'metadata', 'summaryRank'],
action.newRank
)
这将根据需要创建关键字,根据需要使用Immutable的地图。