我正在使用Angular 4和@ngrx 4创建一个Web应用程序,我在配置强类型操作时遇到问题。
我是@ngrx的新手,我为我的行为创建了以下类:
export const ActionTypes = {
LOAD_PRODUCT_TREE: 'load-product-tree',
LOAD_PRODUCT_TREE_COMPLETE: 'load-product-tree-complete'
};
// Load product tree by Id.
export class LoadProductTreeAction implements Action {
type = ActionTypes.LOAD_PRODUCT_TREE;
constructor (public payload: number) { }
}
export class LoadProductTreeCompleteAction implements Action {
type = ActionTypes.LOAD_PRODUCT_TREE_COMPLETE;
constructor (public payload: Map<number, Node>) { }
}
export type Actions = LoadProductTreeAction | LoadProductTreeCompleteAction;
但是当我尝试在我的reducer中使用这些动作时:
export interface State {
productTree: Map<number, Node>;
}
const initialState: State = {
productTree: new Map<number, Node>()
};
export function productTreeReducer(state = initialState, action: productTreeOperations.Actions): State {
switch (action.type) {
case productTreeOperations.ActionTypes.LOAD_PRODUCT_TREE:
return state;
case productTreeOperations.ActionTypes.LOAD_PRODUCT_TREE_COMPLETE:
return { productTree: action.payload };
default:
return state;
}
}
我收到此错误:Type '{ productTree: number | Map<number, Node>; }' is not assignable to type 'State'. Types of property 'productTree' are incompatible. Type 'number | Map<number, Node>' is not assignable to type 'Map<number, Node>'. Type 'number' is not assignable to type 'Map<number, Node>'.
在此行中:return { productTree: action.payload };
如何创建一组采用不同有效负载/参数的操作?
对于减速器中LOAD_PRODUCT_TREE
动作的返回值,最佳做法是什么?我应该在从后端加载信息时返回当前状态,还是应该返回其他内容?
答案 0 :(得分:4)
假设您正在使用框架的默认Action接口,请执行以下重构:
export const LOAD_PRODUCT_TREE = 'load-product-tree';
export const LOAD_PRODUCT_TREE_COMPLETE = 'load-product-tree-complete';
export class LoadProductTreeAction implements Action {
readonly type = LOAD_PRODUCT_TREE;
constructor (public payload: number) { }
}
export class LoadProductTreeCompleteAction implements Action {
readonly type = LOAD_PRODUCT_TREE_COMPLETE;
constructor (public payload: Map<number, Node>) { }
}
export type Actions = LoadProductTreeAction | LoadProductTreeCompleteAction;
export function productTreeReducer(state = initialState, action: productTreeOperations.Actions): State {
switch (action.type) {
case productTreeOperations.LOAD_PRODUCT_TREE:
return state;
case productTreeOperations.LOAD_PRODUCT_TREE_COMPLETE:
return { productTree: action.payload };
default:
return state;
}
}
我稍后会添加相应的解释,但基本上你希望typescript将type
属性识别为单独的类型,而不是字符串。
答案 1 :(得分:0)
问题的关键是readonly
关键字
您需要将操作类型设置为只读
答案 2 :(得分:-2)
我很难阅读你的代码并猜测它,但我认为你有
export class Action{
type: ActionType;
payload: number | Map<number, Node>;
}
然后你有功能:
export function productTreeReducer(state = initialState, action: productTreeOperations.Actions): State {...}
所以你的问题与类型不兼容有关。
State
只能接受Map<>
,但您实际返回Map<> OR number
。在这种情况下,LoadProductTreeCompleteAction
在构造函数中提供Map<>
的事实并不重要,因为payload
值可能会在运行时更改(外部由setter
或内部更改通过状态变化/方法[即使它可能不存在])。
因此,您必须更改State
的签名以接受这两种类型,如果您确定LOAD_PRODUCT_TREE_COMPLETE
始终返回Map<>
,则可以尝试
return { productTree: <Map<number, Node>>action.payload };