diff --git a/react-redux/react-redux-2.1.2-tests.tsx b/react-redux/react-redux-2.1.2-tests.tsx new file mode 100644 index 000000000..cb791a3d8 --- /dev/null +++ b/react-redux/react-redux-2.1.2-tests.tsx @@ -0,0 +1,280 @@ +/// +/// +/// +/// +/// +/// + +import { Component, ReactElement } from 'react'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import * as Router from 'react-router'; +import { Route, RouterState } from 'react-router'; +import { Store, Dispatch, bindActionCreators } from 'redux'; +import { connect, Provider } from 'react-redux'; +import objectAssign = require('object-assign'); + +// +// Quick Start +// https://github.com/rackt/react-redux/blob/master/docs/quick-start.md#quick-start +// + +interface CounterState { + counter: number; +} +declare var increment: Function; + +class Counter extends Component { + render() { + return ( + + ); + } +} + +function mapStateToProps(state: CounterState) { + return { + value: state.counter + }; +} + +// Which action creators does it want to receive by props? +function mapDispatchToProps(dispatch: Dispatch) { + return { + onIncrement: () => dispatch(increment()) + }; +} + +connect( + mapStateToProps, + mapDispatchToProps +)(Counter); + + +@connect(mapStateToProps) +class CounterContainer extends Component { + +} + +class App extends Component { + render(): JSX.Element { + // ... + return null; + } +} + +const targetEl = document.getElementById('root'); + +ReactDOM.render(( + + {() => } + +), targetEl); + +// +// API +// https://github.com/rackt/react-redux/blob/master/docs/api.md +// +declare var routes: Route; +declare var store: Store; +declare var routerState: RouterState; +class MyRootComponent extends Component { + +} +class TodoApp extends Component { + +} +interface TodoState { + todos: string[]|string; +} +interface TodoProps { + userId: number; +} +interface DispatchProps { + addTodo(userId: number, text: string): void; +} +declare var actionCreators: () => { + action: Function; +} +declare var addTodo: () => { type: string; }; +declare var todoActionCreators: { [type: string]: (...args: any[]) => any; }; +declare var counterActionCreators: { [type: string]: (...args: any[]) => any; }; + +ReactDOM.render( + + {() => } + , + document.body +); + +Router.run(routes, Router.HistoryLocation, (Handler, routerState) => { // note "routerState" here + ReactDOM.render( + + {/* + //TODO: error TS2339: Property 'routerState' does not exist on type 'RouteProp'. + {() => } // note "routerState" here: important to pass it down + */} + , + document.getElementById('root') + ); +}); + +//TODO: for React Router 1.0 +//TODO: error TS2604: JSX element type 'Router' does not have any construct or call signatures. +//ReactDOM.render( +// +// {() => ...} +// , +// targetEl +//); + +// Inject just dispatch and don't listen to store + +connect()(TodoApp); + +// Inject dispatch and every field in the global state + +connect((state: TodoState) => state)(TodoApp); + +// Inject dispatch and todos + +function mapStateToProps2(state: TodoState) { + return { todos: state.todos }; +} + +export default connect(mapStateToProps2)(TodoApp); + +// Inject todos and all action creators (addTodo, completeTodo, ...) + +//function mapStateToProps(state) { +// return { todos: state.todos }; +//} + +connect(mapStateToProps2, actionCreators)(TodoApp); + +// Inject todos and all action creators (addTodo, completeTodo, ...) as actions + +//function mapStateToProps(state) { +// return { todos: state.todos }; +//} + +function mapDispatchToProps2(dispatch: Dispatch) { + return { actions: bindActionCreators(actionCreators, dispatch) }; +} + +connect(mapStateToProps2, mapDispatchToProps2)(TodoApp); + +// Inject todos and a specific action creator (addTodo) + +//function mapStateToProps(state) { +// return { todos: state.todos }; +//} + +function mapDispatchToProps3(dispatch: Dispatch) { + return bindActionCreators({ addTodo }, dispatch); +} + +connect(mapStateToProps2, mapDispatchToProps3)(TodoApp); + +// Inject todos, todoActionCreators as todoActions, and counterActionCreators as counterActions + +//function mapStateToProps(state) { +// return { todos: state.todos }; +//} + +function mapDispatchToProps4(dispatch: Dispatch) { + return { + todoActions: bindActionCreators(todoActionCreators, dispatch), + counterActions: bindActionCreators(counterActionCreators, dispatch) + }; +} + +connect(mapStateToProps2, mapDispatchToProps4)(TodoApp); + +// Inject todos, and todoActionCreators and counterActionCreators together as actions + +//function mapStateToProps(state) { +// return { todos: state.todos }; +//} + +function mapDispatchToProps5(dispatch: Dispatch) { + return { + actions: bindActionCreators(objectAssign({}, todoActionCreators, counterActionCreators), dispatch) + }; +} + +connect(mapStateToProps2, mapDispatchToProps5)(TodoApp); + +// Inject todos, and all todoActionCreators and counterActionCreators directly as props + +//function mapStateToProps(state) { +// return { todos: state.todos }; +//} + +function mapDispatchToProps6(dispatch: Dispatch) { + return bindActionCreators(objectAssign({}, todoActionCreators, counterActionCreators), dispatch); +} + +connect(mapStateToProps2, mapDispatchToProps6)(TodoApp); + +// Inject todos of a specific user depending on props + +function mapStateToProps3(state: TodoState, ownProps: TodoProps): TodoState { + return { todos: state.todos[ownProps.userId] }; +} + +connect(mapStateToProps3)(TodoApp); + +// Inject todos of a specific user depending on props, and inject props.userId into the action + +//function mapStateToProps(state) { +// return { todos: state.todos }; +//} + +function mergeProps(stateProps: TodoState, dispatchProps: DispatchProps, ownProps: TodoProps): DispatchProps & TodoState { + return objectAssign({}, ownProps, { + todos: stateProps.todos[ownProps.userId], + addTodo: (text: string) => dispatchProps.addTodo(ownProps.userId, text) + }); +} + +connect(mapStateToProps2, actionCreators, mergeProps)(TodoApp); + + + + + +interface TestProp { + property1: number; + someOtherProperty?: string; +} +interface TestState { + isLoaded: boolean; + state1: number; +} +class TestComponent extends Component { } +const WrappedTestComponent = connect()(TestComponent); + +// return value of the connect()(TestComponent) is of the type TestComponent +let ATestComponent: typeof TestComponent = null; +ATestComponent = TestComponent; +ATestComponent = WrappedTestComponent; + +let anElement: ReactElement; +; +; +; + +class NonComponent {} +// this doesn't compile +//connect()(NonComponent); + +// connect()(SomeClass) has the same constructor as SomeClass itself +class SomeClass extends Component { + constructor(public foo: string) { super() } + public bar: number; +} +let bar: number = new (connect()(SomeClass))("foo").bar; + diff --git a/react-redux/react-redux-2.1.2.d.ts b/react-redux/react-redux-2.1.2.d.ts new file mode 100644 index 000000000..767b6b109 --- /dev/null +++ b/react-redux/react-redux-2.1.2.d.ts @@ -0,0 +1,69 @@ +// Type definitions for react-redux 2.1.2 +// Project: https://github.com/rackt/react-redux +// Definitions by: Qubo +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// +/// + +declare module "react-redux" { + import { Component } from 'react'; + import { Store, Dispatch, ActionCreator } from 'redux'; + + export class ElementClass extends Component { } + export interface ClassDecorator { + (component: T): T + } + + /** + * Connects a React component to a Redux store. + * @param mapStateToProps + * @param mapDispatchToProps + * @param mergeProps + * @param options + */ + export function connect(mapStateToProps?: MapStateToProps, + mapDispatchToProps?: MapDispatchToPropsFunction|MapDispatchToPropsObject, + mergeProps?: MergeProps, + options?: Options): ClassDecorator; + + interface MapStateToProps { + (state: any, ownProps?: any): any; + } + + interface MapDispatchToPropsFunction { + (dispatch: Dispatch, ownProps?: any): any; + } + + interface MapDispatchToPropsObject { + [name: string]: ActionCreator; + } + + interface MergeProps { + (stateProps: any, dispatchProps: any, ownProps: any): any; + } + + interface Options { + /** + * If true, implements shouldComponentUpdate and shallowly compares the result of mergeProps, + * preventing unnecessary updates, assuming that the component is a “pure” component + * and does not rely on any input or state other than its props and the selected Redux store’s state. + * Defaults to true. + * @default true + */ + pure: boolean; + } + + export interface Property { + /** + * The single Redux store in your application. + */ + store?: Store; + children?: Function; + } + + /** + * Makes the Redux store available to the connect() calls in the component hierarchy below. + */ + export class Provider extends Component { } +} diff --git a/react-redux/react-redux-tests.tsx b/react-redux/react-redux-tests.tsx index 3254e6ec7..9ba06ac21 100644 --- a/react-redux/react-redux-tests.tsx +++ b/react-redux/react-redux-tests.tsx @@ -2,14 +2,14 @@ /// /// /// -/// +/// +/// /// import { Component, ReactElement } from 'react'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import * as Router from 'react-router'; -import { Route, RouterState } from 'react-router'; +import { Router, RouterState } from 'react-router'; import { Store, Dispatch, bindActionCreators } from 'redux'; import { connect, Provider } from 'react-redux'; import objectAssign = require('object-assign'); @@ -77,9 +77,9 @@ ReactDOM.render(( // API // https://github.com/rackt/react-redux/blob/master/docs/api.md // -declare var routes: Route; declare var store: Store; declare var routerState: RouterState; +declare var history: HistoryModule.History; class MyRootComponent extends Component { } @@ -109,26 +109,30 @@ ReactDOM.render( document.body ); -Router.run(routes, Router.HistoryLocation, (Handler, routerState) => { // note "routerState" here - ReactDOM.render( - - {/* - //TODO: error TS2339: Property 'routerState' does not exist on type 'RouteProp'. - {() => } // note "routerState" here: important to pass it down - */} - , - document.getElementById('root') - ); -}); +//TODO: for React Router 0.13 +////TODO: error TS2339: Property 'run' does not exist on type 'typeof "react-router"'. +////TODO: error TS2339: Property 'HistoryLocation' does not exist on type 'typeof "react-router"'. +//declare var routes: any; +//Router.run(routes, Router.HistoryLocation, (Handler, routerState) => { // note "routerState" here +// ReactDOM.render( +// +// {/* +// //TODO: error TS2339: Property 'routerState' does not exist on type 'RouteProp'. +// {() => } // note "routerState" here: important to pass it down +// */} +// , +// document.getElementById('root') +// ); +//}); + //TODO: for React Router 1.0 -//TODO: error TS2604: JSX element type 'Router' does not have any construct or call signatures. -//ReactDOM.render( -// -// {() => ...} -// , -// targetEl -//); +ReactDOM.render( + + {() => ...} + , + targetEl +); // Inject just dispatch and don't listen to store @@ -278,3 +282,12 @@ class SomeClass extends Component { } let bar: number = new (connect()(SomeClass))("foo").bar; + +// stateless functions +interface HelloMessageProps { name: string; } +function HelloMessage(props: HelloMessageProps) { + return
Hello {props.name}
; +} +let ConnectedHelloMessage = connect()(HelloMessage); +ReactDOM.render(, document.getElementById('content')); +ReactDOM.render(, document.getElementById('content')); diff --git a/react-redux/react-redux.d.ts b/react-redux/react-redux.d.ts index 767b6b109..9c46fd10c 100644 --- a/react-redux/react-redux.d.ts +++ b/react-redux/react-redux.d.ts @@ -1,4 +1,4 @@ -// Type definitions for react-redux 2.1.2 +// Type definitions for react-redux 4.4.0 // Project: https://github.com/rackt/react-redux // Definitions by: Qubo // Definitions: https://github.com/borisyankov/DefinitelyTyped @@ -7,12 +7,11 @@ /// declare module "react-redux" { - import { Component } from 'react'; + import { ComponentClass, Component, StatelessComponent } from 'react'; import { Store, Dispatch, ActionCreator } from 'redux'; - export class ElementClass extends Component { } - export interface ClassDecorator { - (component: T): T + export interface ComponentConstructDecorator

{ + |StatelessComponent

)>(component: TComponentConstruct): TComponentConstruct } /** @@ -22,10 +21,10 @@ declare module "react-redux" { * @param mergeProps * @param options */ - export function connect(mapStateToProps?: MapStateToProps, - mapDispatchToProps?: MapDispatchToPropsFunction|MapDispatchToPropsObject, - mergeProps?: MergeProps, - options?: Options): ClassDecorator; + export function connect

(mapStateToProps?: MapStateToProps, + mapDispatchToProps?: MapDispatchToPropsFunction|MapDispatchToPropsObject, + mergeProps?: MergeProps, + options?: Options): ComponentConstructDecorator

; interface MapStateToProps { (state: any, ownProps?: any): any;