Angular 财产';有效载荷';不存在于类型';行动';升级@ngrx/Store时

Angular 财产';有效载荷';不存在于类型';行动';升级@ngrx/Store时,angular,typescript,ngrx,ngrx-store,Angular,Typescript,Ngrx,Ngrx Store,我的angular(4.x)应用程序中有@ngrx/store软件包,我正在从v2.2.2->v4.0.0升级。我可以看到迁移说明中说: 已从操作接口中删除有效负载属性 然而,他们给出的例子似乎完全违反直觉(在我看来…) 我有一个减速机函数,如下所示: export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: Action): ITitle { switch (action.type

我的angular(4.x)应用程序中有
@ngrx/store
软件包,我正在从v2.2.2->v4.0.0升级。我可以看到迁移说明中说:

已从操作接口中删除有效负载属性

然而,他们给出的例子似乎完全违反直觉(在我看来…)

我有一个减速机函数,如下所示:

export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: Action): ITitle {
    switch (action.type) {
        case 'SET_TITLE':
            return {
                company: action.payload.company,
                site: action.payload.site,
                department: action.payload.department,
                line: action.payload.line
            }
        case 'RESET':
            return {
                company: 'MyCo',
                site: 'London'
            }
        default:
            return state
    }
}
正如预期的那样,现在抛出typescript错误:

[ts]类型“Action”上不存在属性“payload”


但我从《迁移指南》中也不知道应该改变什么。有什么想法吗?

您可以创建自己的动作类型,该动作类型定义了
有效载荷,请查看参考:

class AddBookAction implements Action {
    readonly type = ADD_BOOK;

    constructor(public payload: Book) {}
}
然后将该类型用于:

可以按如下方式发送操作:

还请注意,示例应用程序将减速器可以采用的所有动作类型合并为一个联合类型:

export type Actions =
    | AddBookAction
    | AddBookSuccessAction

export function reducer(state = initialState, action: Actions): State

好的,这是一个非常有趣的话题。我错过了新的realese(4.0),但我在repo中更新了库,我发现我也有同样的问题

对。已从新版本中的操作中删除有效负载属性。若你们使用特效来分派动作,那个么解决方案很简单,你们能读懂它们吗

但是,如果您希望dispatch传递有效负载,可以通过以下方式创建参数化操作:

export interface ActionWithPayload<T> extends Action {
  payload: T;
} 
export class SomeObject {
    company: string;
    site: string;
    department: string;
    line: string;
}

export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: ActionWithPayload<SomeObject>): ITitle {
    switch (action.type) {
        case 'SET_TITLE':
            return {
                company: action.payload.company,
                site: action.payload.site,
                department: action.payload.department,
                line: action.payload.line
            }
            ...
导出接口操作WithPayload扩展操作{
有效载荷:T;
} 
因此,如果您添加了此接口,您可以通过以下方式更改减速器:

export interface ActionWithPayload<T> extends Action {
  payload: T;
} 
export class SomeObject {
    company: string;
    site: string;
    department: string;
    line: string;
}

export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: ActionWithPayload<SomeObject>): ITitle {
    switch (action.type) {
        case 'SET_TITLE':
            return {
                company: action.payload.company,
                site: action.payload.site,
                department: action.payload.department,
                line: action.payload.line
            }
            ...
导出类SomeObject{
公司名称:字符串;
地点:字符串;
部门:字符串;
行:字符串;
}
导出函数titleEducer(state={company:'MyCo',site:'London'},action:ActionWithPayload):ITitle{
开关(动作类型){
案例“设置标题”:
返回{
公司:action.payload.company,
地点:action.payload.site,
部门:action.payload.department,
行:action.payload.line
}
...

这是我发现的最好的演练。我必须更好地理解这一更改的原因,如果我能找到更好的解决方案,我在这里添加了它们

我还发现这种方法很有用:使用
as
子句导入原始
操作
接口,并使用
有效负载
属性扩展它


在这种情况下,不需要对其余代码进行任何更改:。

是否可以显示操作类的导入?@JaroslawK。
import{ActionReducer,Action}从“@ngrx/store”;
好的,您能展示一下如何使用有效负载调用操作吗?有效还是其他way@JaroslawK.我不太清楚你的意思,上面是我的reducer函数,我将它提供给我的应用程序模块,然后
。选择('title')
在我的组件中。我不会直接调用我所说的任何地方的操作,在哪里发送操作(.dispatch(new Action()或Effect)太棒了,谢谢。如果我确实使用了effects,这会是什么样子?我不确定我是否理解你的问题。你是在问如果使用ActionWithPayload,效果如何?我是在问你的评论“如果您使用效果来调度操作,解决方案很简单",我还不明白迁移说明的前后发生了什么。我想知道基于效果的解决方案可能是什么样子?在比较了上的elvirdolic解决方案和其他答案之后,这是最好的方法。创建操作类,创建实现操作的自定义操作类型,并添加
负载
属性然后分派操作类。干净且更强类型的解决方案。在此解决方案中需要注意的一点是,不应将类型变量声明为某个typescript变量类型。例如(readonly type:string=ADD_BOOK;)将不起作用!(如果我们假设ADD_BOOK常量定义为字符串)。