redux-devtools-extension
redux-devtools-extension copied to clipboard
actionSanitizer & stateSanitizer with TypeScript
Hi !
I'd like to use these EnhancerOptions
with TypeScript and my typed state but can't find a way to set them correctly. I don't want to use any
and to lose types.
Here's a small reproductible example (type StateSanitizer
comes from redux-devtools) :
type AppState = {
msg: string;
secret: string;
}
type StateSanitizer = <S>(state: S) => S;
const state: AppState = { msg: "Hello", secret: "SECRET !" };
const sanitizer: StateSanitizer = (state: AppState) => {
const result = { ...state };
result.secret = '';
return result; // Casting to AppState doesn't help
};
Which result in a compiler error :
Type '(state: AppState) => { msg: string; secret: string; }' is not assignable to type 'StateSanitizer'.
Types of parameters 'state' and 'state' are incompatible.
Type 'S' is not assignable to type 'AppState'.
I tried this too (same error) :
const sanitizer: StateSanitizer = <S extends AppState>(state: S) => {
const result = { ...state };
result.secret = '';
return result as S;
};
I'm probably missing something but can't find what.
Here's my application store creation file :
import { applyMiddleware, createStore } from "redux";
import { composeWithDevTools, EnhancerOptions } from "redux-devtools-extension";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
import { AppState } from "./state";
const stateSanitizer = (state: AppState) => state;
const options: EnhancerOptions = { stateSanitizer };
const composeEnhancers = composeWithDevTools(options);
const store = createStore(
rootReducer,
composeEnhancers(applyMiddleware(thunk))
);
export default store;
Which fails with the same issue at compile-time.
Thanks for you help and suggestions ;-)
Something like this should work:
const composeEnhancers = composeWithDevTools({
stateSanitizer: <S extends Partial<AppState>>(state: S): S => {
const { user, ...rest } = state
return {
...rest
} as S
}
})
That can likely be closed.
Is there a similar example for actionSanitizer
? This is the furthest I've gotten:
actionSanitizer: <S extends Action<string>>(action: S): S => {
if (action.type === 'LOAD_DATA') {
action.data; // TypeScript compiler throws an error on this line
}
return action;
}
I've tried using <S extends Action<string> & {data: any}>
but then I get an error because {data: any}
doesn't fit the type constraint on the function.
Update: I've got it working with the following:
actionSanitizer: <S extends Action<string>>(action: S & {payload: any}): S => {
if (action.type === 'LOAD_DATA') {
action.payload; // This works
}
return action;
}
In my case I'm using flux-standard-action so actions have a payload
attached.
If your action(s) have a payload
prop, you can also use the AnyAction
type from redux:
const actionSanitizer = <A extends AnyAction>(action: A) => {
....
}