Skip to content

Commit 3b4f495

Browse files
timdorrcellognickservjedmao
authored
Merge pull request reduxjs#3536 from reduxjs/ts-conversion
[Meta PR] Convert to TypeScript Co-authored-by: Gregory Beaver <[email protected]> Co-authored-by: Nick McCurdy <[email protected]> Co-authored-by: Jed Mao <[email protected]>
2 parents ca32c4d + 75c882b commit 3b4f495

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1999
-358
lines changed

.babelrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const { NODE_ENV } = process.env
22

33
module.exports = {
44
presets: [
5+
'@babel/typescript',
56
[
67
'@babel/env',
78
{

.eslintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
**/server.js
44
**/webpack.config*.js
55
**/flow-typed/**
6+
# TODO: figure out a way to lint this using flow instead of typescript
7+
examples/todos-flow

.eslintrc.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,34 @@
11
module.exports = {
22
extends: 'react-app',
33

4+
parser: '@typescript-eslint/parser',
5+
6+
plugins: ['@typescript-eslint'],
7+
48
settings: {
59
react: {
610
version: '16.8'
11+
},
12+
'import/parsers': {
13+
'@typescript-eslint/parser': ['.ts', '.tsx']
14+
},
15+
'import/resolver': {
16+
// use <root>/tsconfig.json
17+
typescript: {}
718
}
819
},
920

1021
rules: {
11-
'jsx-a11y/href-no-hash': 'off'
12-
},
13-
14-
overrides: [
15-
{
16-
files: 'test/**/*.js',
17-
env: {
18-
jest: true,
19-
},
20-
},
21-
],
22+
'jsx-a11y/href-no-hash': 'off',
23+
'no-unused-vars': 'off',
24+
'@typescript-eslint/no-unused-vars': [
25+
'error',
26+
{
27+
vars: 'all',
28+
args: 'after-used',
29+
ignoreRestSiblings: true,
30+
argsIgnorePattern: '^_' // ignore unused variables whose name is '_'
31+
}
32+
]
33+
}
2234
}

.gitignore

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
.DS_Store
2-
*.log
31
node_modules
2+
3+
coverage
4+
45
dist
56
lib
67
es
7-
coverage
8+
types
89

910
website/translated_docs
1011
website/build/

examples/todomvc/src/components/App.spec.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import App from './App'
44
import Header from '../containers/Header'
55
import MainSection from '../containers/MainSection'
66

7-
8-
const setup = propOverrides => {
7+
const setup = _propOverrides => {
98
const renderer = createRenderer()
109
renderer.render(<App />)
1110
const output = renderer.getRenderOutput()
@@ -16,16 +15,16 @@ describe('components', () => {
1615
describe('Header', () => {
1716
it('should render', () => {
1817
const output = setup()
19-
const [ header ] = output.props.children
18+
const [header] = output.props.children
2019
expect(header.type).toBe(Header)
2120
})
2221
})
23-
22+
2423
describe('Mainsection', () => {
2524
it('should render', () => {
2625
const output = setup()
27-
const [ , mainSection ] = output.props.children
26+
const [, mainSection] = output.props.children
2827
expect(mainSection.type).toBe(MainSection)
2928
})
3029
})
31-
})
30+
})

index.d.ts

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ export function combineReducers<M extends ReducersMapObject<any, any>>(
211211
* dispatched.
212212
*/
213213
export interface Dispatch<A extends Action = AnyAction> {
214-
<T extends A>(action: T): T
214+
<T extends A>(action: T, ...extraArgs: any[]): T
215215
}
216216

217217
/**
@@ -247,15 +247,33 @@ export type Observer<T> = {
247247
next?(value: T): void
248248
}
249249

250+
/**
251+
* Extend the state
252+
*
253+
* This is used by store enhancers and store creators to extend state.
254+
* If there is no state extension, it just returns the state, as is, otherwise
255+
* it returns the state joined with its extension.
256+
*/
257+
export type ExtendState<State, Extension> = [Extension] extends [never]
258+
? State
259+
: State & Extension
260+
250261
/**
251262
* A store is an object that holds the application's state tree.
252263
* There should only be a single store in a Redux app, as the composition
253264
* happens on the reducer level.
254265
*
255266
* @template S The type of state held by this store.
256267
* @template A the type of actions which may be dispatched by this store.
268+
* @template StateExt any extension to state from store enhancers
269+
* @template Ext any extensions to the store from store enhancers
257270
*/
258-
export interface Store<S = any, A extends Action = AnyAction> {
271+
export interface Store<
272+
S = any,
273+
A extends Action = AnyAction,
274+
StateExt = never,
275+
Ext = {}
276+
> {
259277
/**
260278
* Dispatches an action. It is the only way to trigger a state change.
261279
*
@@ -326,7 +344,9 @@ export interface Store<S = any, A extends Action = AnyAction> {
326344
*
327345
* @param nextReducer The reducer for the store to use instead.
328346
*/
329-
replaceReducer(nextReducer: Reducer<S, A>): void
347+
replaceReducer<NewState, NewActions extends Action>(
348+
nextReducer: Reducer<NewState, NewActions>
349+
): Store<ExtendState<NewState, StateExt>, NewActions, StateExt, Ext> & Ext
330350

331351
/**
332352
* Interoperability point for observable/reactive libraries.
@@ -353,15 +373,15 @@ export type DeepPartial<T> = {
353373
* @template StateExt State extension that is mixed into the state type.
354374
*/
355375
export interface StoreCreator {
356-
<S, A extends Action, Ext, StateExt>(
376+
<S, A extends Action, Ext = {}, StateExt = never>(
357377
reducer: Reducer<S, A>,
358378
enhancer?: StoreEnhancer<Ext, StateExt>
359-
): Store<S & StateExt, A> & Ext
360-
<S, A extends Action, Ext, StateExt>(
379+
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
380+
<S, A extends Action, Ext = {}, StateExt = never>(
361381
reducer: Reducer<S, A>,
362382
preloadedState?: PreloadedState<S>,
363383
enhancer?: StoreEnhancer<Ext>
364-
): Store<S & StateExt, A> & Ext
384+
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
365385
}
366386

367387
/**
@@ -415,16 +435,17 @@ export const createStore: StoreCreator
415435
* @template Ext Store extension that is mixed into the Store type.
416436
* @template StateExt State extension that is mixed into the state type.
417437
*/
418-
export type StoreEnhancer<Ext = {}, StateExt = {}> = (
419-
next: StoreEnhancerStoreCreator
438+
export type StoreEnhancer<Ext = {}, StateExt = never> = (
439+
next: StoreEnhancerStoreCreator<Ext, StateExt>
420440
) => StoreEnhancerStoreCreator<Ext, StateExt>
421-
export type StoreEnhancerStoreCreator<Ext = {}, StateExt = {}> = <
441+
442+
export type StoreEnhancerStoreCreator<Ext = {}, StateExt = never> = <
422443
S = any,
423444
A extends Action = AnyAction
424445
>(
425446
reducer: Reducer<S, A>,
426447
preloadedState?: PreloadedState<S>
427-
) => Store<S & StateExt, A> & Ext
448+
) => Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
428449

429450
/* middleware */
430451

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

669690
export function compose<R>(...funcs: Function[]): (...args: any[]) => R
691+
692+
export const __DO_NOT_USE__ActionTypes: {
693+
INIT: string
694+
REPLACE: string
695+
PROBE_UNKNOWN_ACTION: () => string
696+
}

0 commit comments

Comments
 (0)