diff --git a/package.json b/package.json index ef5ac9f665..3f59918dd7 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ ] }, "jest": { - "testRegex": "(/test/.*\\.spec\\.js)$" + "testRegex": "(/test/.*\\.spec\\.[tj]s)$" }, "sideEffects": false } diff --git a/test/createStore.spec.js b/test/createStore.spec.ts similarity index 90% rename from test/createStore.spec.js rename to test/createStore.spec.ts index f3700e2d6d..5e8ef1db50 100644 --- a/test/createStore.spec.js +++ b/test/createStore.spec.ts @@ -1,4 +1,11 @@ -import { createStore, combineReducers } from '../' +import { + createStore, + combineReducers, + Reducer, + StoreEnhancer, + Action, + Store +} from '..' import { addTodo, dispatchInMiddle, @@ -9,7 +16,7 @@ import { unknownAction } from './helpers/actionCreators' import * as reducers from './helpers/reducers' -import { from } from 'rxjs' +import { from, ObservableInput } from 'rxjs' import { map } from 'rxjs/operators' import $$observable from 'symbol-observable' @@ -26,11 +33,11 @@ describe('createStore', () => { }) it('throws if reducer is not a function', () => { - expect(() => createStore()).toThrow() + expect(() => createStore(undefined)).toThrow() - expect(() => createStore('test')).toThrow() + expect(() => createStore(('test' as unknown) as Reducer)).toThrow() - expect(() => createStore({})).toThrow() + expect(() => createStore(({} as unknown) as Reducer)).toThrow() expect(() => createStore(() => {})).not.toThrow() }) @@ -568,13 +575,23 @@ describe('createStore', () => { }) it('throws if enhancer is neither undefined nor a function', () => { - expect(() => createStore(reducers.todos, undefined, {})).toThrow() + expect(() => + createStore(reducers.todos, undefined, ({} as unknown) as StoreEnhancer) + ).toThrow() - expect(() => createStore(reducers.todos, undefined, [])).toThrow() + expect(() => + createStore(reducers.todos, undefined, ([] as unknown) as StoreEnhancer) + ).toThrow() expect(() => createStore(reducers.todos, undefined, null)).toThrow() - expect(() => createStore(reducers.todos, undefined, false)).toThrow() + expect(() => + createStore( + reducers.todos, + undefined, + (false as unknown) as StoreEnhancer + ) + ).toThrow() expect(() => createStore(reducers.todos, undefined, undefined) @@ -586,25 +603,27 @@ describe('createStore', () => { expect(() => createStore(reducers.todos, [])).not.toThrow() - expect(() => createStore(reducers.todos, {})).not.toThrow() + expect(() => + createStore<{}, Action, {}, {}>(reducers.todos, {}) + ).not.toThrow() }) it('throws if nextReducer is not a function', () => { const store = createStore(reducers.todos) - expect(() => store.replaceReducer()).toThrow( + expect(() => store.replaceReducer(undefined)).toThrow( 'Expected the nextReducer to be a function.' ) - expect(() => store.replaceReducer(() => {})).not.toThrow() + expect(() => store.replaceReducer(() => [])).not.toThrow() }) it('throws if listener is not a function', () => { const store = createStore(reducers.todos) - expect(() => store.subscribe()).toThrow() + expect(() => store.subscribe(undefined)).toThrow() - expect(() => store.subscribe('')).toThrow() + expect(() => store.subscribe(('' as unknown) as () => void)).toThrow() expect(() => store.subscribe(null)).toThrow() @@ -654,11 +673,11 @@ describe('createStore', () => { }) it('should pass an integration test with no unsubscribe', () => { - function foo(state = 0, action) { + function foo(state = 0, action: Action) { return action.type === 'foo' ? 1 : state } - function bar(state = 0, action) { + function bar(state = 0, action: Action) { return action.type === 'bar' ? 2 : state } @@ -667,7 +686,7 @@ describe('createStore', () => { const results = [] observable.subscribe({ - next(state) { + next(state: any) { results.push(state) } }) @@ -683,11 +702,11 @@ describe('createStore', () => { }) it('should pass an integration test with an unsubscribe', () => { - function foo(state = 0, action) { + function foo(state = 0, action: Action) { return action.type === 'foo' ? 1 : state } - function bar(state = 0, action) { + function bar(state = 0, action: Action) { return action.type === 'bar' ? 2 : state } @@ -696,7 +715,7 @@ describe('createStore', () => { const results = [] const sub = observable.subscribe({ - next(state) { + next(state: any) { results.push(state) } }) @@ -709,25 +728,26 @@ describe('createStore', () => { }) it('should pass an integration test with a common library (RxJS)', () => { - function foo(state = 0, action) { + function foo(state = 0, action: Action) { return action.type === 'foo' ? 1 : state } - function bar(state = 0, action) { + function bar(state = 0, action: Action) { return action.type === 'bar' ? 2 : state } - const store = createStore(combineReducers({ foo, bar })) + const store: ObservableInput<{ foo: number; bar: number }> = createStore( + combineReducers({ foo, bar }) + ) const observable = from(store) const results = [] const sub = observable .pipe(map(state => ({ fromRx: true, ...state }))) .subscribe(state => results.push(state)) - - store.dispatch({ type: 'foo' }) + ;(store as Store).dispatch({ type: 'foo' }) sub.unsubscribe() - store.dispatch({ type: 'bar' }) + ;(store as Store).dispatch({ type: 'bar' }) expect(results).toEqual([ { foo: 0, bar: 0, fromRx: true }, @@ -758,7 +778,7 @@ describe('createStore', () => { }) ) - expect(console.error.mock.calls.length).toBe(0) + expect((console.error as any).mock.calls.length).toBe(0) console.error = originalConsoleError }) @@ -766,15 +786,22 @@ describe('createStore', () => { const rootReducer = combineReducers(reducers) const dummyEnhancer = f => f expect(() => - createStore(rootReducer, dummyEnhancer, dummyEnhancer) + // use a fake pre-loaded state to get a valid createStore signature + createStore(rootReducer, (dummyEnhancer as unknown) as {}, dummyEnhancer) ).toThrow() }) it('throws if passing several enhancer functions with preloaded state', () => { const rootReducer = combineReducers(reducers) - const dummyEnhancer = f => f + const dummyEnhancer = (f: any) => f expect(() => - createStore(rootReducer, { todos: [] }, dummyEnhancer, dummyEnhancer) + // work around the type so we can call this poorly + (createStore as any)( + rootReducer, + { todos: [] }, + dummyEnhancer, + dummyEnhancer + ) ).toThrow() }) })