Skip to content

Commit

Permalink
Road to implicitAny part 4 (#4497)
Browse files Browse the repository at this point in the history
What is this?
This PR continues the work on making this project type safe with TypeScript. Goal is that the flag noImplicitAny will be set to true

What this PR does?
* all files inside adapter folder is valid for noImplicitAny!
* resolveAssetSource is now imported from the current place where it should. Previously it was imported from legacy location. More info here: https://facebook.github.io/react-native/docs/image#resolveassetsource
* formatted many files
* add missing interfaces
* fix onPressIn prop on TouchablePreview

What's next?
Next I am planning to make same treatment for commands folder and many it valid for noImplicitAny 🎉
  • Loading branch information
henrikra authored and guyca committed Dec 25, 2018
1 parent 464ee20 commit 02985c5
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 41 deletions.
5 changes: 2 additions & 3 deletions lib/src/adapters/AssetResolver.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
import { ImageRequireSource } from 'react-native';
import { ImageRequireSource, Image } from 'react-native';

export class AssetService {
resolveFromRequire(value: ImageRequireSource) {
return resolveAssetSource(value);
return Image.resolveAssetSource(value);
}
}
18 changes: 6 additions & 12 deletions lib/src/adapters/Element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { requireNativeComponent } from 'react-native';

let RNNElement: React.ComponentType<any>;

export class Element extends React.Component<{ elementId: any; resizeMode?: any; }, any> {
export class Element extends React.Component<{ elementId: any; resizeMode?: any }> {
static propTypes = {
elementId: PropTypes.string.isRequired,
resizeMode: PropTypes.string
Expand All @@ -15,18 +15,12 @@ export class Element extends React.Component<{ elementId: any; resizeMode?: any;
};

render() {
return (
<RNNElement {...this.props} />
);
return <RNNElement {...this.props} />;
}
}

RNNElement = requireNativeComponent(
'RNNElement',
Element,
{
nativeOnly: {
nativeID: true
}
RNNElement = requireNativeComponent('RNNElement', Element, {
nativeOnly: {
nativeID: true
}
);
});
21 changes: 19 additions & 2 deletions lib/src/adapters/NativeCommandsSender.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
import { NativeModules } from 'react-native';

interface NativeCommandsModule {
setRoot(commandId: string, layout: { root: any; modals: any[]; overlays: any[] }): Promise<any>;
setDefaultOptions(options: object): void;
mergeOptions(componentId: string, options: object): void;
push(commandId: string, onComponentId: string, layout: object): Promise<any>;
pop(commandId: string, componentId: string, options?: object): Promise<any>;
popTo(commandId: string, componentId: string, options?: object): Promise<any>;
popToRoot(commandId: string, componentId: string, options?: object): Promise<any>;
setStackRoot(commandId: string, onComponentId: string, layout: object): Promise<any>;
showModal(commandId: string, layout: object): Promise<any>;
dismissModal(commandId: string, componentId: string, options?: object): Promise<any>;
dismissAllModals(commandId: string, options?: object): Promise<any>;
showOverlay(commandId: string, layout: object): Promise<any>;
dismissOverlay(commandId: string, componentId: string): Promise<any>;
getLaunchArgs(commandId: string): Promise<any>;
}

export class NativeCommandsSender {
private readonly nativeCommandsModule;
private readonly nativeCommandsModule: NativeCommandsModule;
constructor() {
this.nativeCommandsModule = NativeModules.RNNBridgeModule;
}

setRoot(commandId: string, layout: { root: any, modals: any[], overlays: any[] }) {
setRoot(commandId: string, layout: { root: any; modals: any[]; overlays: any[] }) {
return this.nativeCommandsModule.setRoot(commandId, layout);
}

Expand Down
4 changes: 3 additions & 1 deletion lib/src/adapters/NativeEventsReceiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import {
import { CommandCompletedEvent, BottomTabSelectedEvent } from '../interfaces/Events';

export class NativeEventsReceiver {
private emitter;
private emitter: { addListener(event: string, callback: any): EventSubscription };
constructor() {
// NOTE: This try catch is workaround for integration tests
// TODO: mock NativeEventEmitter in integration tests rather done adding try catch in source code
try {
this.emitter = new NativeEventEmitter(NativeModules.RNNEventEmitter);
} catch (e) {
Expand Down
38 changes: 19 additions & 19 deletions lib/src/adapters/TouchablePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@ import {
} from 'react-native';

// Polyfill GestureResponderEvent type with additional `force` property (iOS)
interface NativeTouchEventWithForce extends NativeTouchEvent { force: number; }
interface NativeTouchEventWithForce extends NativeTouchEvent {
force: number;
}
interface GestureResponderEventWithForce extends NativeSyntheticEvent<NativeTouchEventWithForce> {}

export interface Props {
children: React.ReactNode;
touchableComponent?: TouchableHighlight | TouchableOpacity | TouchableNativeFeedback | TouchableWithoutFeedback | React.ReactNode;
touchableComponent?:
| TouchableHighlight
| TouchableOpacity
| TouchableNativeFeedback
| TouchableWithoutFeedback
| React.ReactNode;
onPress?: () => void;
onPressIn?: (reactTag?) => void;
onPressIn?: (payload: { reactTag: number | null }) => void;
onPeekIn?: () => void;
onPeekOut?: () => void;
}
Expand All @@ -30,8 +37,7 @@ const PREVIEW_DELAY = 350;
const PREVIEW_MIN_FORCE = 0.1;
const PREVIEW_TIMEOUT = 1250;

export class TouchablePreview extends React.PureComponent<Props, any> {

export class TouchablePreview extends React.PureComponent<Props> {
static propTypes = {
children: PropTypes.node,
touchableComponent: PropTypes.func,
Expand All @@ -48,7 +54,7 @@ export class TouchablePreview extends React.PureComponent<Props, any> {
static peeking = false;

private timeout: number | undefined;
private ts: number = 0;
private touchStartedAt: number = 0;
private onRef = React.createRef<any>();
onPress = () => {
const { onPress } = this.props;
Expand Down Expand Up @@ -79,13 +85,13 @@ export class TouchablePreview extends React.PureComponent<Props, any> {

onTouchStart = (event: GestureResponderEvent) => {
// Store a timstamp of the initial touch start
this.ts = event.nativeEvent.timestamp;
this.touchStartedAt = event.nativeEvent.timestamp;
}

onTouchMove = (event: GestureResponderEventWithForce) => {
clearTimeout(this.timeout);
const { force, timestamp } = event.nativeEvent;
const diff = (timestamp - this.ts);
const diff = timestamp - this.touchStartedAt;

if (force > PREVIEW_MIN_FORCE && diff > PREVIEW_DELAY) {
TouchablePreview.peeking = true;
Expand All @@ -111,21 +117,15 @@ export class TouchablePreview extends React.PureComponent<Props, any> {
const { children, touchableComponent, onPress, onPressIn, ...props } = this.props;

// Default to TouchableWithoutFeedback for iOS if set to TouchableNativeFeedback
const Touchable = (
Platform.OS === 'ios' && touchableComponent instanceof TouchableNativeFeedback
? TouchableWithoutFeedback
: touchableComponent
) as typeof TouchableWithoutFeedback;
const Touchable = (Platform.OS === 'ios' &&
touchableComponent instanceof TouchableNativeFeedback
? TouchableWithoutFeedback
: touchableComponent) as typeof TouchableWithoutFeedback;

// Wrap component with Touchable for handling platform touches
// and a single react View for detecting force and timing.
return (
<Touchable
ref={this.onRef}
onPress={this.onPress}
onPressIn={this.onPressIn}
{...props}
>
<Touchable ref={this.onRef} onPress={this.onPress} onPressIn={this.onPressIn} {...props}>
<View
onTouchStart={this.onTouchStart}
onTouchMove={this.onTouchMove as (event: GestureResponderEvent) => void}
Expand Down
16 changes: 12 additions & 4 deletions lib/src/commands/OptionsProcessor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ describe('navigation options', () => {

beforeEach(() => {
const mockedAssetService = mock(AssetService);
when(mockedAssetService.resolveFromRequire(anyNumber())).thenReturn('lol');
when(mockedAssetService.resolveFromRequire(anyNumber())).thenReturn({
height: 100,
scale: 1,
uri: 'lol',
width: 100
});
const assetService = instance(mockedAssetService);

const mockedColorService = mock(ColorService);
Expand Down Expand Up @@ -60,9 +65,12 @@ describe('navigation options', () => {
};
uut.processOptions(options);
expect(options).toEqual({
backgroundImage: 'lol',
rootBackgroundImage: 'lol',
bottomTab: { icon: 'lol', selectedIcon: 'lol' },
backgroundImage: { height: 100, scale: 1, uri: 'lol', width: 100 },
rootBackgroundImage: { height: 100, scale: 1, uri: 'lol', width: 100 },
bottomTab: {
icon: { height: 100, scale: 1, uri: 'lol', width: 100 },
selectedIcon: { height: 100, scale: 1, uri: 'lol', width: 100 }
}
});
});

Expand Down

0 comments on commit 02985c5

Please sign in to comment.