I am trying to migrate my angular 2 app to angular 4 and ngrx 4.
I am tackling a weird typescript compilation problem that I didn't have before this update. I work in an off line environment, so I cant share the exact code here.
I looked for the problem online, the closest thing I could find was this question: question about payload types The code in this question is somehow similar to what im trying to do, but the difference is that I removed the ActionTypes object from the action (which is the suggest answer for that question) but it did not resolve my compilation error.
I can't put the exact code im tackling with here, but im completely basing my code on the ngrx example ngrx official example on github
Lets look for example on the book reducer and book actions book actions book reducer
My code is basically the same, and the error will occur for each reducer case (in the switch case) when I try to get the payload out of the action, it tells me something like:
Type 'string | Book | Book[]' is not assignable to type 'Book'. Type 'string' is not assignable to type 'Book'.
(In my code, instead of Book I have different classes, but its pretty much the same idea)
For now i'm solving the errors by casting the action type from A | B | B to be the specific action type corresponding to the case in the switch (using the as typescript keyword). This solution feels bad and hacky, I would like to know if there is a better one.
The versions im using: typescript: 2.4.1 (I suspect that it might be connected to ngrx examples not using the same updated typescript version as me) ngrx@store: 4.0.3 ngrx@core: 1.2.0 angular: (latest as of 17.9.17, there are many packages inside angular, and I dont think it accually matters which angular im using for this error but I say this just to be on the safe side) typescript: (2.4.1) (I read the ngrx official migration doc about needing to upgrade typescript, and so I did)
UPDATE: Since I got an answer that isn't relevant to my problem and also I've been asked, here is the part of my code that fails (I cant post the exact post but im hand copying the relevant parts):
mission-reducer.ts:
import * as MissionActionsFile from "./mission-actions";
export type State = .... // doesnt matter
const initialState: State = // doesnt matter as well
export function reducer(state: State = initialState, action:
MissionActionsFile.Actions): State {
switch(action.type) {
case MissionActionsFile.ADD_SUCCESS:
{
const mission: Mission = action.payload; // This line generates the
// following error:
// Type 'string | number | Mission | MissionRealTime | ...' is not
// assignable
// to type 'Mission'. Type 'string' is not assignable to type 'Mission'
return {}; // This doesnt matter too
}
// There are more cases and a deafult one, but that doesn't matter
}
}
mission-actions.ts:
// I will only give the actual action defenition for AddSuccess and for AddFailed since we are using AddSuccess in the example and
// addFailed is an example where the payload type is string, which according to the error is the problem, though
// there are more action types and other payload types with other classes as the quoted error implies.
export const ADD_SUCCESS: string = "[Mission] AddSuccess";
export const ADD_FAILED: string = "[Mission] AddFailed";
export class AddSuccessAction implements Action {
public readonly type: string = ADD_SUCCESS;
constructor(public payload: Mission) {}
}
export class AddFailedAction implements Action {
public readonly type:string = ADD_FAILED;
constructor(public payload: string) {}
}
// More actions are defined here but im not gonna copy all
...
export type Actions =
AddSuccessAction |
AddFailedAction;
So to conclude, I do see why it make sense for typescript to think the action payload type might be string | Mission | ... but in the ngrx example that I based this on, it seems typescript knows there to infer the specific type in the case, but for me that doesn't work for a reason im not understanding, might be something to do with me using typescript 2.4.1? not sure, need help with this