Closed dcs3spp closed 4 years ago
Hi @dcs3spp, Thanks for report.
Mandatory info:
createReducer
? (Check the docs here if you're not sure)Also please paste full reducer code, image is not complete working code.
Hi @piotrwitek, Thanks for responding :) Yes, I have a type declaration file for RootAction, RootState etc. as follows:
declare module 'ReduxTypes' {
import { StateType, ActionType } from 'typesafe-actions';
export type Store = StateType<
typeof import('../app/redux/store/index').default
>;
export type RootState = StateType<
ReturnType<typeof import('../app/redux/store/rootReducer').default>
>;
export type RootAction = ActionType<
typeof import('../app/redux/store/rootAction').default
>;
export type Services = typeof import('../app/services').default;
}
where the rootAction.ts file is defined as....
import * as errorActions from '../features/error/actions';
import * as courseActions from '../features/course/actions';
export default {
errors: errorActions,
courses: courseActions,
};
Full reducer code is:
import { combineReducers } from "redux";
import { createReducer } from "typesafe-actions";
import { ErrorReport } from "./types";
import { clearErrorAction, notifyErrorAction, ClearError } from "./actions";
/**
* Initial State
*/
const initialState: ErrorReport[] = [];
/**
* Helper functions to:
* - addError: Add an error report to state
* - removeError: Remove error report from state
*/
const addError = (
state: ErrorReport[],
newItem: ErrorReport
): ErrorReport[] => {
if (state.find(item => item.sourceComponent === newItem.sourceComponent)) {
// if there is already an error report for source map then replace it
return state.map(item => {
if (item.sourceComponent === newItem.sourceComponent) {
return newItem;
}
return item;
});
} else {
// create a new array with the new item appended
return state.concat([newItem]);
}
};
const removeError = (
state: ErrorReport[],
newItem: ClearError
): ErrorReport[] => {
// return an array that is filtered without including sourcecomponent
const newList: ErrorReport[] = state.filter(
item => item.sourceComponent !== newItem.sourceComponent
);
console.log(
`[Error reducer] removeError => ${JSON.stringify(newList, null, 2)}`
);
return newList;
};
const error = createReducer(initialState as ErrorReport[])
.handleAction([notifyErrorAction], (state, action): ErrorReport[] =>
addError(state, action.payload)
)
.handleAction([clearErrorAction], (state, action): ErrorReport[] =>
removeError(state, action.payload)
);
const errorsReducer = combineReducers({
error
});
/**
* Exports
*/
export default errorsReducer;
export type ErrorState = ReturnType<typeof errorsReducer>;
The issue still happens if I use the createAction function from deprecated. In the meantime, going to revert back to 4.4.2.
Compare this:
Guide:
// types.d.ts
import { StateType, ActionType } from 'typesafe-actions';
export type RootAction = ActionType<typeof import('./actions').default>;
declare module 'typesafe-actions' {
interface Types {
RootAction: RootAction;
}
}
Your code:
declare module 'ReduxTypes' {
import { StateType, ActionType } from 'typesafe-actions';
export type Store = StateType<
typeof import('../app/redux/store/index').default
>;
export type RootState = StateType<
ReturnType<typeof import('../app/redux/store/rootReducer').default>
>;
export type RootAction = ActionType<
typeof import('../app/redux/store/rootAction').default
>;
export type Services = typeof import('../app/services').default;
}
Do you see difference?
You need to fix above to make it work.
Here is the best example from codesanbox: https://github.com/piotrwitek/typesafe-actions/blob/master/codesandbox/src/store/types.d.ts
I'm working on a new tutorial, so this section will be improved.
Many thanks @piotrwitek, that solved it. I changed type declaration file in my src/@types folder to be:
import { StateType, ActionType } from 'typesafe-actions';
declare module 'typesafe-actions' {
export type Store = StateType<
typeof import('../app/redux/store/index').default
>;
export type RootState = StateType<
ReturnType<typeof import('../app/redux/store/rootReducer').default>
>;
export type RootAction = ActionType<
typeof import('../app/redux/store/rootAction').default
>;
export type Services = typeof import('../app/services').default;
interface Types {
RootAction: RootAction;
}
}
Not sure why, but it solved the issue..... Is it something to do with the above type declaration module overriding those in node_modules/typesafe-actions type declarations? Is the Types
interface referenced in createReducer
code....?
Anyway, many thanks again that solved the issue, appreciated :)
@dcs3spp correct it's referenced in createReducer code :) I'm glad it helped to fix your issue!
👍 Many thanks again for your help @piotrwitek. typesafe-actions library a valuable asset for typescript redux developers :)
Description
Hi,
Not sure if this is a bug or my usage error....
I have recently upgraded to v5.1.0 of the library and when declaring the type for the state in a reducer the resulting properties are defined as unknown.
Steps to Reproduce
I have uploaded an example screenshot of reducer code, here, to illustrate what is happening..... The underlines for state and action are linter warnings for usage of any type.
I am defining the action using the new createAction syntax as follows:
Expected behavior
Properties in reducer state type declaration are typed similar to behaviour in version 4.4.2.
Project Dependencies
Environment (optional)