You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular NgRx访问Action属性报TS2339错误如何解决

Angular NgRx TypeScript TS2339类型报错修复方案

报错根因

两处属性不存在的类型错误核心诱因有两个:

  • 定义Action时props未做函数调用。props是NgRx提供的工厂函数,必须加()执行后才能正确挂载自定义属性的类型,直接传入props<{xxx: T}>会导致类型推导断裂,生成的Action类型上不存在你定义的payload/data属性。
  • Effect中触发成功Action时传参格式不匹配,saveUserSuccessAction要求入参结构和props定义一致,直接传入User对象不符合类型要求。

修复步骤

1. 修正Action定义,补全props调用

所有使用props定义的Action都要补上函数调用括号:

// action.ts
export const saveUserAction = createAction(
  '[User] Save',
  props<{ payload: User }>() // 补()执行props
);

export const saveUserSuccessAction = createAction(
  '[User] Save Success',
  props<{ data: User }>() // 补()执行props
);

export const saveUserFailureAction = createAction(
  '[User] Save Failure',
  props<{ error: unknown }>() // 失败Action同理补全
);

2. 修正Effect中的Action传参与冗余类型标注

ofType操作符会自动推导流中的Action类型,不需要手动写ActionType<typeof saveUserAction>标注;触发成功Action时要传入和props结构匹配的对象:

// effect.ts
saveUserEffect$ = createEffect(() => this.actions$.pipe(
    ofType(saveUserAction),
    switchMap((action) => {
      // 类型自动推导为{ payload: User; type: "[User] Save" },访问payload无报错
      return this.userService.saveUser(action.payload).pipe(
        map((user) => {
          // 传入{data: user}匹配props定义的结构
          return saveUserSuccessAction({ data: user })
        }),
        catchError(error => observableOf(saveUserFailureAction({error})))
      )
    })
  ))

3. 优化Reducer参数解构(可选,规范类型)

原代码中处理失败Action时直接取整个action对象作为error,不符合类型定义,解构取error属性即可获得准确类型:

// reducer.ts
export const reducer = createReducer(
  initialState,
  on(loadUsers, (state) => ({...state, isLoading: true})),
  on(UserAction.loadUsersSuccess, (state, {data: users}) => ({...state, data: users, isLoading: false})),
  // 解构action上的error属性
  on(UserAction.loadUsersFailure, (state, {error}) => ({...state, error, isLoading: false})),
  on(saveUserFailureAction, (state, {error}) => ({...state, isLoading: false, error})),
  // 此处data属性类型会被正确推导为User,不再报TS2339
  on(saveUserSuccessAction, (state, {data: user}) => ({...state, isLoading: false, selectedUser: user})),
);

修复效果

  • 全程不需要使用any绕过类型检查,完全保留TypeScript强类型校验能力
  • Action、Effect、Reducer之间的类型会自动关联,属性拼写错误、传参结构错误都会在编译阶段被拦截

内容的提问来源于stack exchange,提问作者Navigator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:36:32