licancabur
licancabur

Reputation: 645

flow typing mismatch for function accepting a reducer

I want to create a function which does something to a reducer (it's not important what it is, just some transformation, similar to combineReducers). i have problem when i want to abstract the state for the reducer. Here is the simplified reducer used for some component:

type someState = {
  foo: number,
};
export const someSimpleReducer = (state: someState) => state;

type StateAbstract = {}; // this doesn't work
// type StateAbstract = any; // this works

and here the abstract transform function with abstracted state:

declare type SimpleReducer<S> = (state: S) => S;

export const transformReducer = (reducer: SimpleReducer<StateAbstract>) => ({
  reducer,
});

transformReducer(someSimpleReducer);

i see the following flow error:

Flow: Cannot call transformReducer with someSimpleReducer bound to reducer because property foo is missing in StateAbstract [1] but exists in someState [2] in the first argument

If i use type StateAbstract = any then i don't see any error... How can i write StateAbstract type so it's not any, but is an object?

Upvotes: 0

Views: 142

Answers (1)

Stefan
Stefan

Reputation: 675

declare type SimpleReducer<S> = (state: S) => S;

declares a type SimpleReducer which is a function that takes an S and returns an S.

transformReducer is a function that takes a SimpleReducer<StateAbstract> i.e. a function that takes a StateAbstract and returns a StateAbstract.

transformReducer shouldn't care about what type that reducer function takes and returns. Instead of using a concrete type use a generic:

export const transformReducer = <S>(reducer: SimpleReducer<S>) => ({reducer})

Here it is on Try Flow.

Upvotes: 1

Related Questions