From d4a4c4472d03f21cb43bbeb66c7bff1e5405bdfa Mon Sep 17 00:00:00 2001 From: Paul Marbach Date: Wed, 24 Jul 2019 15:06:59 -0500 Subject: [PATCH] [@types/combine-reducers] initial commit (#37090) --- .../combine-reducers-tests.ts | 36 +++++++ types/combine-reducers/index.d.ts | 100 ++++++++++++++++++ types/combine-reducers/tsconfig.json | 23 ++++ types/combine-reducers/tslint.json | 1 + 4 files changed, 160 insertions(+) create mode 100644 types/combine-reducers/combine-reducers-tests.ts create mode 100644 types/combine-reducers/index.d.ts create mode 100644 types/combine-reducers/tsconfig.json create mode 100644 types/combine-reducers/tslint.json diff --git a/types/combine-reducers/combine-reducers-tests.ts b/types/combine-reducers/combine-reducers-tests.ts new file mode 100644 index 0000000000..0e55c13bf0 --- /dev/null +++ b/types/combine-reducers/combine-reducers-tests.ts @@ -0,0 +1,36 @@ +import combineReducers from 'combine-reducers'; + +function counter(state: number = 0, action: { type: string; payload?: any }): number { + if (action.type === 'increment_counter') { + return (state += 1); + } else if (action.type === 'decrement_counter') { + return (state -= 1); + } + return state; +} + +function toggle(state: boolean = false, action: { type: string; payload?: any }): boolean { + if (action.type === 'toggle') { + return action.payload; + } + return state; +} + +const reducer = combineReducers({ + toggle, + counter, +}); + +// $ExpectError +combineReducers(); + +reducer({ toggle: false, counter: 4 }, { type: 'increment_counter' }); +reducer({ toggle: false, counter: 4 }, { type: 'decrement_counter' }); +reducer({ toggle: true, counter: 4 }, { type: 'toggle', payload: false }); + +// $ExpectError +reducer({ toggle: false, counter: 4, extra: false }, { type: 'decrement_counter' }); +// $ExpectError +reducer({ toggle: false, counter: 4, extra: false }); +// $ExpectError +reducer({ toggle: 3, counter: 4 }, { type: 'decrement_counter' }); diff --git a/types/combine-reducers/index.d.ts b/types/combine-reducers/index.d.ts new file mode 100644 index 0000000000..bd400e73d5 --- /dev/null +++ b/types/combine-reducers/index.d.ts @@ -0,0 +1,100 @@ +// Type definitions for combine-reducers 1.0 +// Project: https://github.com/wesleytodd/combine-reducers#readme +// Definitions by: Paul Marbach +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +/** + * these types are from the main redux type definitions: + * https://github.com/reduxjs/redux/blob/master/index.d.ts + */ + +/** + * An *action* is a plain object that represents an intention to change the + * state. Actions are the only way to get data into the store. Any data, + * whether from UI events, network callbacks, or other sources such as + * WebSockets needs to eventually be dispatched as actions. + * + * Actions must have a `type` field that indicates the type of action being + * performed. Types can be defined as constants and imported from another + * module. It's better to use strings for `type` than Symbols because strings + * are serializable. + * + * Other than `type`, the structure of an action object is really up to you. + * If you're interested, check out Flux Standard Action for recommendations on + * how actions should be constructed. + * + * @template T the type of the action's `type` tag. + */ +export interface Action { + type: T; +} + +/** + * An Action type which accepts any other properties. + * This is mainly for the use of the `Reducer` type. + * This is not part of `Action` itself to prevent types that extend `Action` from + * having an index signature. + */ +export interface AnyAction extends Action { + // Allows any extra properties to be defined in an action. + [extraProps: string]: any; +} + +/* reducers */ + +/** + * A *reducer* (also called a *reducing function*) is a function that accepts + * an accumulation and a value and returns a new accumulation. They are used + * to reduce a collection of values down to a single value + * + * Reducers are not unique to Redux—they are a fundamental concept in + * functional programming. Even most non-functional languages, like + * JavaScript, have a built-in API for reducing. In JavaScript, it's + * `Array.prototype.reduce()`. + * + * In Redux, the accumulated value is the state object, and the values being + * accumulated are actions. Reducers calculate a new state given the previous + * state and an action. They must be *pure functions*—functions that return + * the exact same output for given inputs. They should also be free of + * side-effects. This is what enables exciting features like hot reloading and + * time travel. + * + * Reducers are the most important concept in Redux. + * + * *Do not put API calls into reducers.* + * + * @template S The type of state consumed and produced by this reducer. + * @template A The type of actions the reducer can potentially respond to. + */ +export type Reducer = (state: S | undefined, action: A) => S; + +/** + * Object whose values correspond to different reducer functions. + * + * @template A The type of actions the reducers can potentially respond to. + */ +export type ReducersMapObject = { + [K in keyof S]: Reducer; +}; + +/** + * Turns an object whose values are different reducer functions, into a single + * reducer function. It will call every child reducer, and gather their results + * into a single state object, whose keys correspond to the keys of the passed + * reducer functions. + * + * @template S Combined state object type. + * + * @param reducers An object whose values correspond to different reducer + * functions that need to be combined into one. One handy way to obtain it + * is to use ES6 `import * as reducers` syntax. The reducers may never + * return undefined for any action. Instead, they should return their + * initial state if the state passed to them was undefined, and the current + * state for any unrecognized action. + * + * @returns A reducer function that invokes every reducer inside the passed + * object, and builds a state object with the same shape. + */ +export default function combineReducers(reducers: ReducersMapObject): Reducer; +export default function combineReducers(reducers: ReducersMapObject): Reducer; diff --git a/types/combine-reducers/tsconfig.json b/types/combine-reducers/tsconfig.json new file mode 100644 index 0000000000..4632c31e7f --- /dev/null +++ b/types/combine-reducers/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "combine-reducers-tests.ts" + ] +} diff --git a/types/combine-reducers/tslint.json b/types/combine-reducers/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/combine-reducers/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }