首页 > 解决方案 > @ngrx/reducer:createReducer() 和 on() 不是类型安全的?

问题描述

当使用以前版本的ngrx我没有使用 createAction()andcreateReducer()时,如果我尝试添加不属于提供的任何其他属性,则会引发错误State

我将应用程序升级到Angular 8,并且也在使用ngrx 8.3.0。现在似乎类型安全不再存在,尽管NGRX文档指出大多数类型推断都将被实现。

someState.ts

export interface ISampleState {
  id: number
}

someAction.ts

export const request = createAction('[SAMPLE] Request', props<{id: number}>();

someReducer.ts

const initialState: ISampleState = {
  id: null
}

const sampleReducer = createReducer(
  initialState,
  on(SampleActions.request, (state, { id }) => {
    return {
      ...state,
      id,
      // Below would previously complain since only `id` is defined in the `ISampleState`
      thisShouldNormallyComplain: 'but it does not'
    }
  }
);

// AOT purposes
export function reducer(state: ISampleState | undefined, action: Action): ISampleState {
  return sampleReducer(state, action);
}

在实际运行代码之后,我会看到DevTools商店确实填充了这个无根据的属性。

我最担心的是当我在return块内的减速器中有错字时,它也不会抱怨。

即如果我不小心输入

return {
   ...state,
   Id: id  //should be `id`
}

很难找到错误,因为它编译得很好,没有抱怨。

有任何想法吗?

标签: angularngrx

解决方案


玩了一会儿,这似乎是 TypeScript 的问题!createReducer最终创建ActionReducer<S, A>一个签名为(state: S | undefined, action: A) => S.

在这种情况下,TypeScript 似乎允许任何满足此签名的可调用来满足参数,即使返回的类型具有比实际更多的属性S。我已经针对编译器提交了这个错误,因为对我来说这似乎不是正确的行为。


推荐阅读