Skip to content

Commit

Permalink
Merge pull request reduxjs#3536 from reduxjs/ts-conversion
Browse files Browse the repository at this point in the history
[Meta PR] Convert to TypeScript

Co-authored-by: Gregory Beaver <greg.beaver.cello@gmail.com>
Co-authored-by: Nick McCurdy <nick@nickmccurdy.com>
Co-authored-by: Jed Mao <jedmao@users.noreply.github.com>
  • Loading branch information
4 people committed Sep 6, 2019
2 parents ca32c4d + 75c882b commit 3b4f495
Show file tree
Hide file tree
Showing 51 changed files with 1,999 additions and 358 deletions.
1 change: 1 addition & 0 deletions .babelrc.js
Expand Up @@ -2,6 +2,7 @@ const { NODE_ENV } = process.env

module.exports = {
presets: [
'@babel/typescript',
[
'@babel/env',
{
Expand Down
2 changes: 2 additions & 0 deletions .eslintignore
Expand Up @@ -3,3 +3,5 @@
**/server.js
**/webpack.config*.js
**/flow-typed/**
# TODO: figure out a way to lint this using flow instead of typescript
examples/todos-flow
34 changes: 23 additions & 11 deletions .eslintrc.js
@@ -1,22 +1,34 @@
module.exports = {
extends: 'react-app',

parser: '@typescript-eslint/parser',

plugins: ['@typescript-eslint'],

settings: {
react: {
version: '16.8'
},
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx']
},
'import/resolver': {
// use <root>/tsconfig.json
typescript: {}
}
},

rules: {
'jsx-a11y/href-no-hash': 'off'
},

overrides: [
{
files: 'test/**/*.js',
env: {
jest: true,
},
},
],
'jsx-a11y/href-no-hash': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
vars: 'all',
args: 'after-used',
ignoreRestSiblings: true,
argsIgnorePattern: '^_' // ignore unused variables whose name is '_'
}
]
}
}
7 changes: 4 additions & 3 deletions .gitignore
@@ -1,10 +1,11 @@
.DS_Store
*.log
node_modules

coverage

dist
lib
es
coverage
types

website/translated_docs
website/build/
Expand Down
11 changes: 5 additions & 6 deletions examples/todomvc/src/components/App.spec.js
Expand Up @@ -4,8 +4,7 @@ import App from './App'
import Header from '../containers/Header'
import MainSection from '../containers/MainSection'


const setup = propOverrides => {
const setup = _propOverrides => {
const renderer = createRenderer()
renderer.render(<App />)
const output = renderer.getRenderOutput()
Expand All @@ -16,16 +15,16 @@ describe('components', () => {
describe('Header', () => {
it('should render', () => {
const output = setup()
const [ header ] = output.props.children
const [header] = output.props.children
expect(header.type).toBe(Header)
})
})

describe('Mainsection', () => {
it('should render', () => {
const output = setup()
const [ , mainSection ] = output.props.children
const [, mainSection] = output.props.children
expect(mainSection.type).toBe(MainSection)
})
})
})
})
49 changes: 38 additions & 11 deletions index.d.ts
Expand Up @@ -211,7 +211,7 @@ export function combineReducers<M extends ReducersMapObject<any, any>>(
* dispatched.
*/
export interface Dispatch<A extends Action = AnyAction> {
<T extends A>(action: T): T
<T extends A>(action: T, ...extraArgs: any[]): T
}

/**
Expand Down Expand Up @@ -247,15 +247,33 @@ export type Observer<T> = {
next?(value: T): void
}

/**
* Extend the state
*
* This is used by store enhancers and store creators to extend state.
* If there is no state extension, it just returns the state, as is, otherwise
* it returns the state joined with its extension.
*/
export type ExtendState<State, Extension> = [Extension] extends [never]
? State
: State & Extension

/**
* A store is an object that holds the application's state tree.
* There should only be a single store in a Redux app, as the composition
* happens on the reducer level.
*
* @template S The type of state held by this store.
* @template A the type of actions which may be dispatched by this store.
* @template StateExt any extension to state from store enhancers
* @template Ext any extensions to the store from store enhancers
*/
export interface Store<S = any, A extends Action = AnyAction> {
export interface Store<
S = any,
A extends Action = AnyAction,
StateExt = never,
Ext = {}
> {
/**
* Dispatches an action. It is the only way to trigger a state change.
*
Expand Down Expand Up @@ -326,7 +344,9 @@ export interface Store<S = any, A extends Action = AnyAction> {
*
* @param nextReducer The reducer for the store to use instead.
*/
replaceReducer(nextReducer: Reducer<S, A>): void
replaceReducer<NewState, NewActions extends Action>(
nextReducer: Reducer<NewState, NewActions>
): Store<ExtendState<NewState, StateExt>, NewActions, StateExt, Ext> & Ext

/**
* Interoperability point for observable/reactive libraries.
Expand All @@ -353,15 +373,15 @@ export type DeepPartial<T> = {
* @template StateExt State extension that is mixed into the state type.
*/
export interface StoreCreator {
<S, A extends Action, Ext, StateExt>(
<S, A extends Action, Ext = {}, StateExt = never>(
reducer: Reducer<S, A>,
enhancer?: StoreEnhancer<Ext, StateExt>
): Store<S & StateExt, A> & Ext
<S, A extends Action, Ext, StateExt>(
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
<S, A extends Action, Ext = {}, StateExt = never>(
reducer: Reducer<S, A>,
preloadedState?: PreloadedState<S>,
enhancer?: StoreEnhancer<Ext>
): Store<S & StateExt, A> & Ext
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
}

/**
Expand Down Expand Up @@ -415,16 +435,17 @@ export const createStore: StoreCreator
* @template Ext Store extension that is mixed into the Store type.
* @template StateExt State extension that is mixed into the state type.
*/
export type StoreEnhancer<Ext = {}, StateExt = {}> = (
next: StoreEnhancerStoreCreator
export type StoreEnhancer<Ext = {}, StateExt = never> = (
next: StoreEnhancerStoreCreator<Ext, StateExt>
) => StoreEnhancerStoreCreator<Ext, StateExt>
export type StoreEnhancerStoreCreator<Ext = {}, StateExt = {}> = <

export type StoreEnhancerStoreCreator<Ext = {}, StateExt = never> = <
S = any,
A extends Action = AnyAction
>(
reducer: Reducer<S, A>,
preloadedState?: PreloadedState<S>
) => Store<S & StateExt, A> & Ext
) => Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext

/* middleware */

Expand Down Expand Up @@ -667,3 +688,9 @@ export function compose<R>(
): (...args: any[]) => R

export function compose<R>(...funcs: Function[]): (...args: any[]) => R

export const __DO_NOT_USE__ActionTypes: {
INIT: string
REPLACE: string
PROBE_UNKNOWN_ACTION: () => string
}

0 comments on commit 3b4f495

Please sign in to comment.