mirror of
https://github.com/zhigang1992/DefinitelyTyped.git
synced 2026-05-16 19:09:18 +08:00
Merge pull request #11101 from JProgrammer/react-redux-decorator
Strictly typed component decorator support
This commit is contained in:
@@ -10,7 +10,7 @@ import { Component, ReactElement } from 'react';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { Router, RouterState } from 'react-router';
|
||||
import { Store, Dispatch, bindActionCreators } from 'redux';
|
||||
import { Store, Dispatch, bindActionCreators, Action } from 'redux';
|
||||
import { connect, Provider } from 'react-redux';
|
||||
import objectAssign = require('object-assign');
|
||||
|
||||
@@ -20,11 +20,17 @@ import objectAssign = require('object-assign');
|
||||
//
|
||||
|
||||
interface CounterState {
|
||||
counter: number;
|
||||
counter: number
|
||||
}
|
||||
declare var increment: Function;
|
||||
|
||||
class Counter extends Component<any, any> {
|
||||
declare var increment: () => Action
|
||||
|
||||
interface CounterProps {
|
||||
value: number,
|
||||
onIncrement: Function
|
||||
}
|
||||
|
||||
class CounterAny extends Component<any, any> {
|
||||
render() {
|
||||
return (
|
||||
<button onClick={this.props.onIncrement}>
|
||||
@@ -34,6 +40,15 @@ class Counter extends Component<any, any> {
|
||||
}
|
||||
}
|
||||
|
||||
class Counter extends Component<CounterProps, any> {
|
||||
render() {
|
||||
return (
|
||||
<button onClick={this.props.onIncrement}>
|
||||
{this.props.value}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
function mapStateToProps(state: CounterState) {
|
||||
return {
|
||||
value: state.counter
|
||||
@@ -41,7 +56,7 @@ function mapStateToProps(state: CounterState) {
|
||||
}
|
||||
|
||||
// Which action creators does it want to receive by props?
|
||||
function mapDispatchToProps(dispatch: Dispatch<CounterState>) {
|
||||
function mapDispatchToProps(dispatch: Dispatch<Action>) {
|
||||
return {
|
||||
onIncrement: () => dispatch(increment())
|
||||
};
|
||||
@@ -50,12 +65,13 @@ function mapDispatchToProps(dispatch: Dispatch<CounterState>) {
|
||||
connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Counter);
|
||||
|
||||
)(CounterAny);
|
||||
|
||||
@connect(mapStateToProps)
|
||||
class CounterContainer extends Component<any, any> {
|
||||
|
||||
render() {
|
||||
return <CounterAny {...this.props}/>
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure connect's first two arguments can be replaced by wrapper functions
|
||||
@@ -87,6 +103,12 @@ connect<ICounterStateProps, ICounterDispatchProps, {}>(
|
||||
{ pure: true }
|
||||
)(Counter);
|
||||
|
||||
@connect<ICounterStateProps, ICounterDispatchProps, any, any>(mapStateToProps, mapDispatchToProps)
|
||||
class CounterDispatchContainer extends Component<ICounterStateProps & ICounterDispatchProps, any> {
|
||||
render() {
|
||||
return <Counter {...this.props}/>
|
||||
}
|
||||
}
|
||||
|
||||
class App extends Component<any, any> {
|
||||
render(): JSX.Element {
|
||||
|
||||
81
react-redux/react-redux.d.ts
vendored
81
react-redux/react-redux.d.ts
vendored
@@ -14,51 +14,72 @@ declare namespace ReactRedux {
|
||||
type Dispatch<S> = Redux.Dispatch<S>;
|
||||
type ActionCreator<A> = Redux.ActionCreator<A>;
|
||||
|
||||
interface ComponentDecorator<TOriginalProps, TOwnProps> {
|
||||
(component: ComponentClass<TOriginalProps>|StatelessComponent<TOriginalProps>): ComponentClass<TOwnProps>;
|
||||
|
||||
interface ComponentConstructor<P, S> extends __React.ComponentLifecycle<P, S> {
|
||||
new(props?: P, context?: S) : void;
|
||||
}
|
||||
|
||||
interface ComponentClassDecorator<TOriginalProps, TOwnProps> {
|
||||
(component: ComponentConstructor<TOriginalProps, any> | ComponentClass<TOriginalProps> | StatelessComponent<TOriginalProps>): ComponentClass<TOwnProps>;
|
||||
}
|
||||
|
||||
interface ComponentDecorator<TOriginalProps, TOwnProps, TState> {
|
||||
(constructor: ComponentConstructor<TOriginalProps, TState>): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorator that infers the type from the original component
|
||||
*
|
||||
* Can't use the above decorator because it would default the type to {}
|
||||
*/
|
||||
* Decorator that infers the type from the original component
|
||||
*
|
||||
* Can't use the above decorator because it would default the type to {}
|
||||
*/
|
||||
export interface InferableComponentDecorator {
|
||||
<P, TComponentConstruct extends (ComponentClass<P>|StatelessComponent<P>)>(component: TComponentConstruct): TComponentConstruct;
|
||||
<P, TComponentConstruct extends (ComponentClass<P> | StatelessComponent<P>)>(component: TComponentConstruct): TComponentConstruct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects a React component to a Redux store.
|
||||
*
|
||||
* - Without arguments, just wraps the component, without changing the behavior / props
|
||||
*
|
||||
* - If 2 params are passed (3rd param, mergeProps, is skipped), default behavior
|
||||
* is to override ownProps (as stated in the docs), so what remains is everything that's
|
||||
* not a state or dispatch prop
|
||||
*
|
||||
* - When 3rd param is passed, we don't know if ownProps propagate and whether they
|
||||
* should be valid component props, because it depends on mergeProps implementation.
|
||||
* As such, it is the user's responsibility to extend ownProps interface from state or
|
||||
* dispatch props or both when applicable
|
||||
*
|
||||
* @param mapStateToProps
|
||||
* @param mapDispatchToProps
|
||||
* @param mergeProps
|
||||
* @param options
|
||||
*/
|
||||
* Connects a React component to a Redux store.
|
||||
*
|
||||
* - Without arguments, just wraps the component, without changing the behavior / props
|
||||
*
|
||||
* - If 2 params are passed (3rd param, mergeProps, is skipped), default behavior
|
||||
* is to override ownProps (as stated in the docs), so what remains is everything that's
|
||||
* not a state or dispatch prop
|
||||
*
|
||||
* - When 3rd param is passed, we don't know if ownProps propagate and whether they
|
||||
* should be valid component props, because it depends on mergeProps implementation.
|
||||
* As such, it is the user's responsibility to extend ownProps interface from state or
|
||||
* dispatch props or both when applicable
|
||||
*
|
||||
* @param mapStateToProps
|
||||
* @param mapDispatchToProps
|
||||
* @param mergeProps
|
||||
* @param options
|
||||
*/
|
||||
export function connect(): InferableComponentDecorator;
|
||||
|
||||
export function connect<TStateProps, TDispatchProps, TOwnProps>(
|
||||
mapStateToProps: FuncOrSelf<MapStateToProps<TStateProps, TOwnProps>>,
|
||||
mapDispatchToProps?: FuncOrSelf<MapDispatchToPropsFunction<TDispatchProps, TOwnProps>|MapDispatchToPropsObject>
|
||||
): ComponentDecorator<TStateProps & TDispatchProps, TOwnProps>;
|
||||
mapDispatchToProps?: FuncOrSelf<MapDispatchToPropsFunction<TDispatchProps, TOwnProps> | MapDispatchToPropsObject>
|
||||
): ComponentClassDecorator<TStateProps & TDispatchProps, TOwnProps>;
|
||||
|
||||
export function connect<TStateProps, TDispatchProps, TOwnProps>(
|
||||
mapStateToProps: FuncOrSelf<MapStateToProps<TStateProps, TOwnProps>>,
|
||||
mapDispatchToProps: FuncOrSelf<MapDispatchToPropsFunction<TDispatchProps, TOwnProps>|MapDispatchToPropsObject>,
|
||||
mapDispatchToProps: FuncOrSelf<MapDispatchToPropsFunction<TDispatchProps, TOwnProps> | MapDispatchToPropsObject>,
|
||||
mergeProps: MergeProps<TStateProps, TDispatchProps, TOwnProps>,
|
||||
options?: Options
|
||||
): ComponentDecorator<TStateProps & TDispatchProps, TOwnProps>;
|
||||
): ComponentClassDecorator<TStateProps & TDispatchProps, TOwnProps>;
|
||||
|
||||
export function connect<TStateProps, TDispatchProps, TOwnProps, TState>(
|
||||
mapStateToProps: FuncOrSelf<MapStateToProps<TStateProps, TOwnProps>>,
|
||||
mapDispatchToProps?: FuncOrSelf<MapDispatchToPropsFunction<TDispatchProps, TOwnProps> | MapDispatchToPropsObject>
|
||||
): ComponentDecorator<TStateProps & TDispatchProps, TOwnProps, TState>;
|
||||
|
||||
export function connect<TStateProps, TDispatchProps, TOwnProps, TState>(
|
||||
mapStateToProps: FuncOrSelf<MapStateToProps<TStateProps, TOwnProps>>,
|
||||
mapDispatchToProps: FuncOrSelf<MapDispatchToPropsFunction<TDispatchProps, TOwnProps> | MapDispatchToPropsObject>,
|
||||
mergeProps: MergeProps<TStateProps, TDispatchProps, TOwnProps>,
|
||||
options?: Options
|
||||
): ComponentDecorator<TStateProps & TDispatchProps, TOwnProps, TState>;
|
||||
|
||||
type FuncOrSelf<T> = T | (() => T);
|
||||
|
||||
@@ -88,7 +109,7 @@ declare namespace ReactRedux {
|
||||
*/
|
||||
pure?: boolean;
|
||||
/**
|
||||
* If true, stores a ref to the wrapped component instance and makes it available via
|
||||
* If true, stores a ref to the wrapped component instance and makes it available via
|
||||
* getWrappedInstance() method. Defaults to false.
|
||||
*/
|
||||
withRef?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user