Skip to content

Instantly share code, notes, and snippets.

@damaon
Last active April 27, 2017 14:52
Show Gist options
  • Select an option

  • Save damaon/884dda839ad34a69bfff29981e4868d0 to your computer and use it in GitHub Desktop.

Select an option

Save damaon/884dda839ad34a69bfff29981e4868d0 to your computer and use it in GitHub Desktop.
type ReduxAction = { type: string };
type Reducer<T> = (T, ReduxAction) => T;
type ReducerDefinition<T> = { [ACTION_TYPE: string]: (ReduxAction) => (T) => T };
export function createReducer<T>(
initialState: T,
definition: ReducerDefinition<T>
): Reducer<T> {
return (state: T = initialState, action: ReduxAction): T => {
const actionResponse = definition[action.type];
return actionResponse ? actionResponse(action)(state) : state;
};
}
type Foo = {| foo: string |};
const init: Foo = { foo: "foo" };
const reducer = createReducer(
init,
{
"TEST": function(action){
return function(state) {
state.foo; // <- Error! property foo not found in state literal
return { bar: "bar" }; // <- no error. I expect error as init of Foo type doesn't contain bar property.
};
},
}
@damaon
Copy link
Author

damaon commented Apr 27, 2017

I don't why:

  1. state.foo returns an error.foo property belong to type Foo

  2. return { bar: "bar" } is legal. It's incompatible with init of type Foo

@damaon
Copy link
Author

damaon commented Apr 27, 2017

Ok because inference works backward also, the error messages are confusing but they do show up and all that is needed to make it correct is to simply explicitly define type of reducer.

const reducer: Reducer<Foo> = createReducer...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment