angular - NGRX/Store confusão de tipo de payload
Eu tenho as seguintes ações:
export const ActionTypes = {
CREATE_OH: type('[ORDERHEAD] Create Orderhead'),
MODIFY_SELECTED_OH: type('[ORDERHEAD] Select Orderhead'),
};
export class CreateOHAction implements Action {
type = ActionTypes.CREATE_OH
constructor(public payload: OrderHead[]) { }
}
export type Actions
= CreateOHAction
| SelectOHAction;
Com a seguinte configuração básica de reducer
export interface State {
orderids: string[];
entities: { [orderID: string]: OrderHead };
selectedOhID: string | null;
};
// Set initial state to empty
const initialState: State = {
orderids : [],
entities: {},
selectedOhID: null,
};
export function OHreducer(state = initialState, action: orderhead_imp.Actions): State{
switch(action.type){
case orderhead_imp.ActionTypes.CREATE_OH:
let orders = action.payload;
let newOrders = orders.filter(orderhead => !state.entities[orderhead.orderID]);
let newOrderIds = newOrders.map(orderhead => orderhead.orderID);
let newOrderHeadEntities = newOrders.reduce((entities: { [orderID: string]: OrderHead }, orderhead: OrderHead) => {
return Object.assign(entities, {
[orderhead.orderID]: orderhead
});
}, {});
return {
orderids: [ ...state.orderids, ...newOrderIds ],
entities: Object.assign({}, state.entities, newOrderHeadEntities),
selectedOhID: state.selectedOhID
};
default:
return state;
};
}
Isso funciona bem, no entanto, se eu introduzir outra ação:
export class SelectOHAction implements Action {
type = ActionTypes.MODIFY_SELECTED_OH
constructor(public payload: string) { }
}
Observe, o payload apenas para esta ação é uma string, assim que isso é salvo, ou tentado compilar, o TypeScript agora declara: "filter não existe no tipo string|OrderHead[]"
Agora, se eu for para o meu reducer e adicionar um novo caso:
case orderhead_imp.ActionTypes.MODIFY_SELECTED_OH: {
return {
orderids: state.orderids,
entities: state.entities,
selectedOhID: action.payload
};
}
Eu recebo os erros do TypeScript ao mapear action.payload de:
Gera o erro TS "string|OrderHead[] não é atribuível ao tipo string"
Obviamente, em ambos os casos, o payload tem uma estrutura de dados diferente. Preciso mudar meu código de alguma outra forma para garantir que cada caso esteja capturando o tipo correto para action.payload?
Atualização
Então, se em minhas ações eu definir o payload como "any" em vez de "string", parece que compila e funciona sem problemas, no entanto, isso parece muito improvisado (e não é o comportamento esperado)
export class SelectOHAction implements Action {
type = ActionTypes.MODIFY_SELECTED_OH
constructor(public payload: any) { }
}
Resposta #1
Este é um problema com o Typescript >2.1 e o utilitário de tipos do ngrx.
Com o TypeScript 2.1 e superior, agora você pode simplesmente definir ações como
export const CREATE_OH: '[ORDERHEAD] Create Orderhead';
export class CreateOHAction implements Action {
type = CREATE_OH
constructor(public payload: OrderHead[]) { }
}
Agora, em todos os lugares onde você usou item.ActionTypes.CREATE_OH, substitua por item.CREATE_OH. Os tipos serão transmitidos como esperado com o TypeScript 2.1
