Closed
Description
With the current type definition of StoreEnhancer
:
export type StoreEnhancer<S> = (next: StoreEnhancerStoreCreator<S>) => StoreEnhancerStoreCreator<S>;
export type GenericStoreEnhancer = <S>(next: StoreEnhancerStoreCreator<S>) => StoreEnhancerStoreCreator<S>;
export type StoreEnhancerStoreCreator<S> = (reducer: Reducer<S>, initialState: S) => Store<S>;
We cannot define an enhancer that change the type of the sate :
declare function reducerWithFoo<S>(reducer: Reducer<S>): Reducer<S & { foo: string }>;
function test<S>(next: StoreEnhancerStoreCreator<S>): StoreEnhancerStoreCreator<S & { foo: string }> {
return (reducer: Reducer<S>, initialSate: S & { foo: string }) => next(reducerWithFoo(reducer), initialSate);
}
Here we try to create an enhancer that add a foo
field to the sate, but typescript errors saying (in short) that S
is not compatible with S & { foo: string }
.
This is due to the fact that the next
function passed as arguments is not generic and so cannot capture the type from arguments.
Perhaps the solution would be to add a generic version of the StoreEnhancerStoreCreator
type, and to change the signature of StoreEnhancer to use that type for the next
argument.
definitions :
export type StoreEnhancer<S> = (next: GenericStoreEnhancerCreator) => StoreEnhancerStoreCreator<S>;
export type GenericStoreEnhancer = <S>(next: GenericStoreEnhancerCreator) => StoreEnhancerStoreCreator<S>;
export type StoreEnhancerStoreCreator<S> = (reducer: Reducer<S>, initialState: S) => Store<S>;
export type GenericStoreEnhancerCreator = <S>(reducer: Reducer<S>, initialState: S) => Store<S>;
example:
declare function reducerWithFoo<S>(reducer: Reducer<S>): Reducer<S & { foo: string }>;
function test<S>(next: GenericStoreEnhancerCreator): StoreEnhancerStoreCreator<S & { foo: string }> {
return (reducer: Reducer<S>, initialSate: S & { foo: string }) => next(reducerWithFoo(reducer), initialSate);
} // no error