Browse Source

Clean up some implicit Anys (#4235)

Increase type safety in 3 most important files
Henrik Raitasola 6 years ago
parent
commit
e93424de51

+ 11
- 6
lib/src/Navigation.ts View File

62
    * Utility helper function like registerComponent,
62
    * Utility helper function like registerComponent,
63
    * wraps the provided component with a react-redux Provider with the passed redux store
63
    * wraps the provided component with a react-redux Provider with the passed redux store
64
    */
64
    */
65
-  public registerComponentWithRedux(componentName: string, getComponentClassFunc: ComponentProvider, ReduxProvider: any, reduxStore: any): ComponentType<any> {
65
+  public registerComponentWithRedux(
66
+    componentName: string,
67
+    getComponentClassFunc: ComponentProvider,
68
+    ReduxProvider: any,
69
+    reduxStore: any
70
+  ): ComponentType<any> {
66
     return this.componentRegistry.registerComponent(componentName, getComponentClassFunc, ReduxProvider, reduxStore);
71
     return this.componentRegistry.registerComponent(componentName, getComponentClassFunc, ReduxProvider, reduxStore);
67
   }
72
   }
68
 
73
 
97
   /**
102
   /**
98
    * Dismiss a modal by componentId. The dismissed modal can be anywhere in the stack.
103
    * Dismiss a modal by componentId. The dismissed modal can be anywhere in the stack.
99
    */
104
    */
100
-  public dismissModal(componentId: string, mergeOptions?): Promise<any> {
105
+  public dismissModal(componentId: string, mergeOptions?: Options): Promise<any> {
101
     return this.commands.dismissModal(componentId, mergeOptions);
106
     return this.commands.dismissModal(componentId, mergeOptions);
102
   }
107
   }
103
 
108
 
104
   /**
109
   /**
105
    * Dismiss all Modals
110
    * Dismiss all Modals
106
    */
111
    */
107
-  public dismissAllModals(mergeOptions?): Promise<any> {
112
+  public dismissAllModals(mergeOptions?: Options): Promise<any> {
108
     return this.commands.dismissAllModals(mergeOptions);
113
     return this.commands.dismissAllModals(mergeOptions);
109
   }
114
   }
110
 
115
 
118
   /**
123
   /**
119
    * Pop a component from the stack, regardless of it's position.
124
    * Pop a component from the stack, regardless of it's position.
120
    */
125
    */
121
-  public pop(componentId: string, mergeOptions?): Promise<any> {
126
+  public pop(componentId: string, mergeOptions?: Options): Promise<any> {
122
     return this.commands.pop(componentId, mergeOptions);
127
     return this.commands.pop(componentId, mergeOptions);
123
   }
128
   }
124
 
129
 
125
   /**
130
   /**
126
    * Pop the stack to a given component
131
    * Pop the stack to a given component
127
    */
132
    */
128
-  public popTo(componentId: string, mergeOptions?): Promise<any> {
133
+  public popTo(componentId: string, mergeOptions?: Options): Promise<any> {
129
     return this.commands.popTo(componentId, mergeOptions);
134
     return this.commands.popTo(componentId, mergeOptions);
130
   }
135
   }
131
 
136
 
132
   /**
137
   /**
133
    * Pop the component's stack to root.
138
    * Pop the component's stack to root.
134
    */
139
    */
135
-  public popToRoot(componentId: string, mergeOptions?): Promise<any> {
140
+  public popToRoot(componentId: string, mergeOptions?: Options): Promise<any> {
136
     return this.commands.popToRoot(componentId, mergeOptions);
141
     return this.commands.popToRoot(componentId, mergeOptions);
137
   }
142
   }
138
 
143
 

+ 1
- 1
lib/src/commands/Commands.test.ts View File

382
       const mockParser = { parse: () => 'parsed' };
382
       const mockParser = { parse: () => 'parsed' };
383
       const mockCrawler = { crawl: (x) => x, processOptions: (x) => x };
383
       const mockCrawler = { crawl: (x) => x, processOptions: (x) => x };
384
       commandsObserver.register(cb);
384
       commandsObserver.register(cb);
385
-      uut = new Commands(mockCommandsSender, mockParser, mockCrawler, commandsObserver, new UniqueIdProvider());
385
+      uut = new Commands(mockCommandsSender, mockParser as any, mockCrawler as any, commandsObserver, new UniqueIdProvider());
386
     });
386
     });
387
 
387
 
388
     function getAllMethodsOfUut() {
388
     function getAllMethodsOfUut() {

+ 5
- 3
lib/src/commands/Commands.ts View File

4
 import { UniqueIdProvider } from '../adapters/UniqueIdProvider';
4
 import { UniqueIdProvider } from '../adapters/UniqueIdProvider';
5
 import { Options } from '../interfaces/Options';
5
 import { Options } from '../interfaces/Options';
6
 import { Layout, LayoutRoot } from '../interfaces/Layout';
6
 import { Layout, LayoutRoot } from '../interfaces/Layout';
7
+import { LayoutTreeParser } from './LayoutTreeParser';
8
+import { LayoutTreeCrawler } from './LayoutTreeCrawler';
7
 
9
 
8
 export class Commands {
10
 export class Commands {
9
   constructor(
11
   constructor(
10
     private readonly nativeCommandsSender: NativeCommandsSender,
12
     private readonly nativeCommandsSender: NativeCommandsSender,
11
-    private readonly layoutTreeParser,
12
-    private readonly layoutTreeCrawler,
13
+    private readonly layoutTreeParser: LayoutTreeParser,
14
+    private readonly layoutTreeCrawler: LayoutTreeCrawler,
13
     private readonly commandsObserver: CommandsObserver,
15
     private readonly commandsObserver: CommandsObserver,
14
     private readonly uniqueIdProvider: UniqueIdProvider) {
16
     private readonly uniqueIdProvider: UniqueIdProvider) {
15
   }
17
   }
64
     return result;
66
     return result;
65
   }
67
   }
66
 
68
 
67
-  public dismissModal(componentId, mergeOptions?: Options) {
69
+  public dismissModal(componentId: string, mergeOptions?: Options) {
68
     const commandId = this.uniqueIdProvider.generate('dismissModal');
70
     const commandId = this.uniqueIdProvider.generate('dismissModal');
69
     const result = this.nativeCommandsSender.dismissModal(commandId, componentId, mergeOptions);
71
     const result = this.nativeCommandsSender.dismissModal(commandId, componentId, mergeOptions);
70
     this.commandsObserver.notify('dismissModal', { commandId, componentId, mergeOptions});
72
     this.commandsObserver.notify('dismissModal', { commandId, componentId, mergeOptions});

+ 2
- 2
lib/src/components/ComponentRegistry.ts View File

7
 export class ComponentRegistry {
7
 export class ComponentRegistry {
8
   constructor(private readonly store: Store, private readonly componentEventsObserver: ComponentEventsObserver) { }
8
   constructor(private readonly store: Store, private readonly componentEventsObserver: ComponentEventsObserver) { }
9
 
9
 
10
-  registerComponent(componentName: string, getComponentClassFunc: ComponentProvider, ReduxProvider?: any, userStore?: any): ComponentType<any> {
10
+  registerComponent(componentName: string, getComponentClassFunc: ComponentProvider, ReduxProvider?: any, reduxStore?: any): ComponentType<any> {
11
     const OriginalComponentClass = getComponentClassFunc();
11
     const OriginalComponentClass = getComponentClassFunc();
12
-    const NavigationComponent = ComponentWrapper.wrap(componentName, OriginalComponentClass, this.store, this.componentEventsObserver, ReduxProvider, userStore);
12
+    const NavigationComponent = ComponentWrapper.wrap(componentName, OriginalComponentClass, this.store, this.componentEventsObserver, ReduxProvider, reduxStore);
13
     this.store.setOriginalComponentClassForName(componentName, OriginalComponentClass);
13
     this.store.setOriginalComponentClassForName(componentName, OriginalComponentClass);
14
     AppRegistry.registerComponent(componentName, () => NavigationComponent);
14
     AppRegistry.registerComponent(componentName, () => NavigationComponent);
15
     return NavigationComponent;
15
     return NavigationComponent;

+ 8
- 3
lib/src/components/ComponentWrapper.test.tsx View File

3
 import * as renderer from 'react-test-renderer';
3
 import * as renderer from 'react-test-renderer';
4
 import { ComponentWrapper } from './ComponentWrapper';
4
 import { ComponentWrapper } from './ComponentWrapper';
5
 import { Store } from './Store';
5
 import { Store } from './Store';
6
+import { mock, verify, instance } from 'ts-mockito';
7
+import { ComponentEventsObserver } from '../events/ComponentEventsObserver';
6
 
8
 
7
 describe('ComponentWrapper', () => {
9
 describe('ComponentWrapper', () => {
8
   const componentName = 'example.MyComponent';
10
   const componentName = 'example.MyComponent';
9
   let store;
11
   let store;
10
   let myComponentProps;
12
   let myComponentProps;
11
-  const componentEventsObserver = { unmounted: jest.fn() };
13
+  let mockedComponentEventsObserver: ComponentEventsObserver;
14
+  let componentEventsObserver: ComponentEventsObserver;
12
 
15
 
13
   class MyComponent extends React.Component<any, any> {
16
   class MyComponent extends React.Component<any, any> {
14
     static options = {
17
     static options = {
45
 
48
 
46
   beforeEach(() => {
49
   beforeEach(() => {
47
     store = new Store();
50
     store = new Store();
51
+    mockedComponentEventsObserver = mock(ComponentEventsObserver);
52
+    componentEventsObserver = instance(mockedComponentEventsObserver);
48
   });
53
   });
49
 
54
 
50
   it('must have componentId as prop', () => {
55
   it('must have componentId as prop', () => {
130
   it(`calls unmounted on componentEventsObserver`, () => {
135
   it(`calls unmounted on componentEventsObserver`, () => {
131
     const NavigationComponent = ComponentWrapper.wrap(componentName, MyComponent, store, componentEventsObserver);
136
     const NavigationComponent = ComponentWrapper.wrap(componentName, MyComponent, store, componentEventsObserver);
132
     const tree = renderer.create(<NavigationComponent componentId={'component123'} />);
137
     const tree = renderer.create(<NavigationComponent componentId={'component123'} />);
133
-    expect(componentEventsObserver.unmounted).not.toHaveBeenCalled();
138
+    verify(mockedComponentEventsObserver.unmounted('component123')).never();
134
     tree.unmount();
139
     tree.unmount();
135
-    expect(componentEventsObserver.unmounted).toHaveBeenCalledTimes(1);
140
+    verify(mockedComponentEventsObserver.unmounted('component123')).once();
136
   });
141
   });
137
 
142
 
138
   describe(`register with redux store`, () => {
143
   describe(`register with redux store`, () => {

+ 15
- 12
lib/src/components/ComponentWrapper.tsx View File

1
 import * as React from 'react';
1
 import * as React from 'react';
2
 import * as  _ from 'lodash';
2
 import * as  _ from 'lodash';
3
 import * as ReactLifecyclesCompat from 'react-lifecycles-compat';
3
 import * as ReactLifecyclesCompat from 'react-lifecycles-compat';
4
+import { Store } from './Store';
5
+import { ComponentEventsObserver } from '../events/ComponentEventsObserver';
4
 
6
 
5
-export class ComponentWrapper {
7
+interface HocState { componentId: string; allProps: {}; }
8
+interface HocProps { componentId: string; }
6
 
9
 
10
+export class ComponentWrapper {
7
   static wrap(
11
   static wrap(
8
     componentName: string,
12
     componentName: string,
9
     OriginalComponentClass: React.ComponentType<any>,
13
     OriginalComponentClass: React.ComponentType<any>,
10
-    store,
11
-    componentEventsObserver,
12
-    ReduxProvider?,
13
-    reduxStore?): React.ComponentType<any> {
14
-
15
-    class WrappedComponent extends React.Component<any, { componentId: string; allProps: {}; }> {
16
-
17
-      static getDerivedStateFromProps(nextProps, prevState) {
14
+    store: Store,
15
+    componentEventsObserver: ComponentEventsObserver,
16
+    ReduxProvider?: any,
17
+    reduxStore?: any
18
+  ): React.ComponentClass<any> {
19
+    class WrappedComponent extends React.Component<HocProps, HocState> {
20
+      static getDerivedStateFromProps(nextProps: any, prevState: HocState) {
18
         return {
21
         return {
19
           allProps: _.merge({}, nextProps, store.getPropsForId(prevState.componentId))
22
           allProps: _.merge({}, nextProps, store.getPropsForId(prevState.componentId))
20
         };
23
         };
21
       }
24
       }
22
 
25
 
23
-      constructor(props) {
26
+      constructor(props: HocProps) {
24
         super(props);
27
         super(props);
25
         this._assertComponentId();
28
         this._assertComponentId();
26
         this.state = {
29
         this.state = {
54
     ReactLifecyclesCompat.polyfill(WrappedComponent);
57
     ReactLifecyclesCompat.polyfill(WrappedComponent);
55
     require('hoist-non-react-statics')(WrappedComponent, OriginalComponentClass);
58
     require('hoist-non-react-statics')(WrappedComponent, OriginalComponentClass);
56
 
59
 
57
-    if (reduxStore) {
60
+    if (reduxStore && ReduxProvider) {
58
       return ComponentWrapper.wrapWithRedux(WrappedComponent, ReduxProvider, reduxStore);
61
       return ComponentWrapper.wrapWithRedux(WrappedComponent, ReduxProvider, reduxStore);
59
     } else {
62
     } else {
60
       return WrappedComponent;
63
       return WrappedComponent;
61
     }
64
     }
62
   }
65
   }
63
 
66
 
64
-  static wrapWithRedux(WrappedComponent, ReduxProvider, reduxStore): React.ComponentType<any> {
67
+  static wrapWithRedux(WrappedComponent: React.ComponentClass<any>, ReduxProvider: any, reduxStore: any): React.ComponentClass<any> {
65
     class ReduxWrapper extends React.Component<any, any> {
68
     class ReduxWrapper extends React.Component<any, any> {
66
       render() {
69
       render() {
67
         return (
70
         return (

+ 1
- 0
package.json View File

77
     "remx": "2.x.x",
77
     "remx": "2.x.x",
78
     "semver": "5.x.x",
78
     "semver": "5.x.x",
79
     "shell-utils": "1.x.x",
79
     "shell-utils": "1.x.x",
80
+    "ts-mockito": "^2.3.1",
80
     "ts-node": "5.x.x",
81
     "ts-node": "5.x.x",
81
     "tslint": "5.x.x",
82
     "tslint": "5.x.x",
82
     "typedoc": "0.x.x",
83
     "typedoc": "0.x.x",