diff --git a/types/recompose/index.d.ts b/types/recompose/index.d.ts index 5fe0c82987..a9d807360b 100644 --- a/types/recompose/index.d.ts +++ b/types/recompose/index.d.ts @@ -78,13 +78,13 @@ declare module 'recompose' { // withHandlers: https://github.com/acdlite/recompose/blob/master/docs/API.md#withhandlers type EventHandler = Function; - type HandleCreators = { - [handlerName: string]: mapper; + type HandleCreators = { + [handlerName in keyof THandlers]: mapper; }; - type HandleCreatorsFactory = (initialProps: TOutter) => HandleCreators; + type HandleCreatorsFactory = (initialProps: TOutter) => HandleCreators; export function withHandlers( - handlerCreators: HandleCreators | HandleCreatorsFactory - ): InferableComponentEnhancerWithProps; + handlerCreators: HandleCreators | HandleCreatorsFactory + ): InferableComponentEnhancerWithProps; // defaultProps: https://github.com/acdlite/recompose/blob/master/docs/API.md#defaultprops export function defaultProps( @@ -134,13 +134,16 @@ declare module 'recompose' { // withStateHandlers: https://github.com/acdlite/recompose/blob/master/docs/API.md#withstatehandlers type StateHandler = (...payload: any[]) => TState | undefined; - type StateUpdaters = { - [updaterName: string]: (state: TState, props: TOutter) => StateHandler; + type StateHandlerMap = { + [updaterName: string]: StateHandler; }; - export function withStateHandlers( + type StateUpdaters = { + [updaterName in keyof TUpdaters]: (state: TState, props: TOutter) => StateHandler; + }; + export function withStateHandlers, TOutter = {}>( createProps: TState | mapper, - stateUpdaters: StateUpdaters, - ): InferableComponentEnhancerWithProps; + stateUpdaters: StateUpdaters, + ): InferableComponentEnhancerWithProps; // withReducer: https://github.com/acdlite/recompose/blob/master/docs/API.md#withReducer type reducer = (s: TState, a: TAction) => TState; diff --git a/types/recompose/recompose-tests.tsx b/types/recompose/recompose-tests.tsx index 3bffa12cc6..1504ab563a 100644 --- a/types/recompose/recompose-tests.tsx +++ b/types/recompose/recompose-tests.tsx @@ -18,6 +18,8 @@ import { createEventHandlerWithConfig, componentFromStreamWithConfig, mapPropsStreamWithConfig, setObservableConfig, + StateHandler, + StateHandlerMap, } from "recompose"; import rxjsconfig from "recompose/rxjsObservableConfig"; import rxjs4config from "recompose/rxjs4ObservableConfig"; @@ -81,20 +83,20 @@ function testWithPropsOnChange() { } function testWithHandlers() { + interface OutterProps { + out: number; + } interface InnerProps { - onSubmit: React.MouseEventHandler; - onChange: Function; foo: string; } interface HandlerProps { onSubmit: React.MouseEventHandler; onChange: Function; } - interface OutterProps { out: number; } - const InnerComponent: React.StatelessComponent = ({onChange, onSubmit}) => -
; + const InnerComponent: React.StatelessComponent = ({onChange, onSubmit, foo}) => +
{foo}
; - const enhancer = withHandlers({ + const enhancer = withHandlers({ onChange: (props) => (e: any) => {}, onSubmit: (props) => (e: React.MouseEvent) => {}, }); @@ -106,7 +108,7 @@ function testWithHandlers() { /> ) - const enhancer2 = withHandlers((props) => ({ + const enhancer2 = withHandlers((props) => ({ onChange: (props) => (e: any) => {}, onSubmit: (props) => (e: React.MouseEvent) => {}, })); @@ -117,6 +119,11 @@ function testWithHandlers() { out={42} /> ) + + const handlerNameTypecheckProof = withHandlers({ + onChange: () => () => {}, + notAKeyOnHandlerProps: () => () => {}, // $ExpectError + }); } function testDefaultProps() { @@ -186,11 +193,14 @@ function testWithState() { function testWithStateHandlers() { interface State { counter: number; } - interface Updaters { add: (n: number) => State; } - type InnerProps = State & Updaters; + interface Updaters extends StateHandlerMap { + add: StateHandler; + } interface OutterProps { initialCounter: number, power: number } + type InnerProps = State & Updaters & OutterProps; const InnerComponent: React.StatelessComponent = (props) =>
+
{`Initial counter: ${props.initialCounter}`}
{`Counter: ${props.counter}`}
props.add(2)}>
; @@ -205,7 +215,12 @@ function testWithStateHandlers() { const rendered = ( ); -} + + const updateNameTypecheckProof = withStateHandlers( + (props: OutterProps) => ({ counter: props.initialCounter }), + { notAKeyOfUpdaters: (state, props) => n => ({ ...state, counter: state.counter + n ** props.power }), }, // $ExpectError + ); + } function testWithReducer() { interface State { count: number }