When using previous versions of ngrx
where I didn't use
createAction()
and createReducer()
, it would throw an error if I try to add any additional attributes that were not part of the provided State
.
I upgraded the app to Angular 8
, and using ngrx 8.3.0
as well. Now it seems like the type safety is not there anymore, even though NGRX
documentation points out that most of the type inference will be implemented.
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);
}
After actually running the code, I would see via DevTools
that the store is indeed populated with this unwarranted attribute.
My biggest concern is when I have a typo in the reducer within the return
block, it would also not complain.
i.e. If I accidentally type
return {
...state,
Id: id //should be `id`
}
it would be difficult to locate the error since it compiles just fine without complaints.
Any ideas?
Having played with this a bit, it seems like this is a problem with TypeScript! createReducer
ultimately creates an ActionReducer<S, A>
which has a signature of (state: S | undefined, action: A) => S
.
In this case, TypeScript seems to allow any callable that satisfies this signature to satisfy the argument, even if the returned type has more properties than S
does. I've filed this bug against the compiler because to me that doesn't seem to be correct behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With