From bcdeda5dabbed2b7f7bc5d033867e2cab2f904ba Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sat, 27 May 2017 10:43:04 -0700 Subject: [PATCH] [fix] Flow type checking and annotations Fixes dozens of Flow errors; adds type annotations; marks more files for Flow type checking. Fixes a bug in 'AppState'. 15 Flow errors remaining. Several React Native files are still not type checked (e.g., PanResponder, Touchables) Ref #465 --- .eslintrc | 11 ++++++- docs/storybook/demos/TicTacToe/TicTacToe.js | 8 +++-- src/apis/AppRegistry/ReactNativeApp.js | 4 +++ src/apis/AppState/index.js | 6 +++- src/apis/AsyncStorage/index.js | 2 ++ src/apis/BackAndroid/index.js | 4 +-- src/apis/Clipboard/index.js | 3 ++ src/apis/Dimensions/index.js | 12 ++++++- src/apis/I18nManager/index.js | 10 ++++-- src/apis/InteractionManager/index.js | 2 +- src/apis/Linking/index.js | 9 +++-- src/apis/NetInfo/index.js | 4 +-- src/apis/Platform/index.js | 4 +++ src/apis/StyleSheet/flattenStyle.js | 5 ++- src/apis/Vibration/index.js | 10 ++++-- src/components/ActivityIndicator/index.js | 4 +++ src/components/Button/index.js | 4 +++ src/components/Image/ImageResizeMode.js | 4 +++ src/components/Image/ImageStylePropTypes.js | 4 +++ src/components/Image/ImageUriCache.js | 4 +++ src/components/Image/index.js | 14 ++++++-- src/components/ProgressBar/index.js | 4 +++ src/components/ScrollView/ScrollViewBase.js | 21 +++++------- src/components/ScrollView/index.js | 4 +-- src/components/StatusBar/index.js | 4 +++ src/components/Switch/index.js | 6 ++++ src/components/Text/TextStylePropTypes.js | 4 +++ src/components/Text/index.js | 4 +++ .../TextInput/TextInputStylePropTypes.js | 4 +++ src/components/TextInput/index.js | 6 ++++ .../Touchable/TouchableWithoutFeedback.js | 3 +- src/components/View/ViewPropTypes.js | 4 +++ src/components/View/ViewStylePropTypes.js | 4 +++ src/components/View/index.js | 4 +++ src/modules/NativeMethodsMixin/index.js | 33 +++++++++++++++++-- src/modules/applyLayout/index.js | 2 +- src/modules/applyNativeMethods/index.js | 2 +- src/propTypes/EdgeInsetsPropType.js | 11 +++++-- src/propTypes/StyleSheetPropType.js | 10 +++--- types/fbjs.js | 6 +--- 40 files changed, 212 insertions(+), 52 deletions(-) diff --git a/.eslintrc b/.eslintrc index ea3da1c9..5127cd73 100644 --- a/.eslintrc +++ b/.eslintrc @@ -24,7 +24,16 @@ "globals": { "document": false, "navigator": false, - "window": false + "window": false, + // Flow global types + "HTMLInputElement": false, + "ReactClass": false, + "ReactComponent": false, + "ReactElement": false, + "ReactPropsChainableTypeChecker": false, + "ReactPropsCheckType": false, + "ReactPropTypes": false, + "SyntheticEvent": false }, "rules": { "camelcase": 0, diff --git a/docs/storybook/demos/TicTacToe/TicTacToe.js b/docs/storybook/demos/TicTacToe/TicTacToe.js index bca9e18f..497f5ec5 100644 --- a/docs/storybook/demos/TicTacToe/TicTacToe.js +++ b/docs/storybook/demos/TicTacToe/TicTacToe.js @@ -188,7 +188,7 @@ const GameEndOverlay = createReactClass({ const TicTacToeApp = createReactClass({ getInitialState() { - return { board: new Board(), player: 1 } + return { board: new Board(), player: 1 }; }, restartGame() { @@ -214,7 +214,11 @@ const TicTacToeApp = createReactClass({ const rows = this.state.board.grid.map((cells, row) => ( {cells.map((player, col) => ( - + ))} )); diff --git a/src/apis/AppRegistry/ReactNativeApp.js b/src/apis/AppRegistry/ReactNativeApp.js index 447244cf..765ef97b 100644 --- a/src/apis/AppRegistry/ReactNativeApp.js +++ b/src/apis/AppRegistry/ReactNativeApp.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import StyleSheet from '../StyleSheet'; import View from '../../components/View'; import { any, object } from 'prop-types'; diff --git a/src/apis/AppState/index.js b/src/apis/AppState/index.js index a0bd64d4..7db14dc0 100644 --- a/src/apis/AppState/index.js +++ b/src/apis/AppState/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment'; import findIndex from 'array-find-index'; import invariant from 'fbjs/lib/invariant'; @@ -17,7 +21,7 @@ class AppState { static get currentState() { if (!AppState.isAvailable) { - return AppState.ACTIVE; + return AppStates.ACTIVE; } switch (document.visibilityState) { diff --git a/src/apis/AsyncStorage/index.js b/src/apis/AsyncStorage/index.js index 3ecf7be1..dd6e274a 100644 --- a/src/apis/AsyncStorage/index.js +++ b/src/apis/AsyncStorage/index.js @@ -2,6 +2,8 @@ * Copyright (c) 2015-present, Nicolas Gallagher. * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. + * + * @flow */ import merge from 'deep-assign'; diff --git a/src/apis/BackAndroid/index.js b/src/apis/BackAndroid/index.js index e5a97c65..3ad9e13a 100644 --- a/src/apis/BackAndroid/index.js +++ b/src/apis/BackAndroid/index.js @@ -8,11 +8,9 @@ * * web stub for BackAndroid.android.js * - * @providesModule BackAndroid + * @flow */ -'use strict'; - function emptyFunction() {} const BackAndroid = { diff --git a/src/apis/Clipboard/index.js b/src/apis/Clipboard/index.js index 2efa5e50..4fe4c66a 100644 --- a/src/apis/Clipboard/index.js +++ b/src/apis/Clipboard/index.js @@ -1,4 +1,7 @@ /* global window */ +/** + * @flow + */ class Clipboard { static isSupported() { diff --git a/src/apis/Dimensions/index.js b/src/apis/Dimensions/index.js index 7fb7907a..8a9c97cd 100644 --- a/src/apis/Dimensions/index.js +++ b/src/apis/Dimensions/index.js @@ -10,7 +10,17 @@ import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment'; import debounce from 'debounce'; import invariant from 'fbjs/lib/invariant'; -const win = canUseDOM ? window : { screen: {} }; +const win = canUseDOM + ? window + : { + devicePixelRatio: undefined, + innerHeight: undefined, + innerWidth: undefined, + screen: { + height: undefined, + width: undefined + } + }; const dimensions = {}; diff --git a/src/apis/I18nManager/index.js b/src/apis/I18nManager/index.js index ccae8fd7..21529cb0 100644 --- a/src/apis/I18nManager/index.js +++ b/src/apis/I18nManager/index.js @@ -1,9 +1,13 @@ +/** + * @flow + */ + import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment'; type I18nManagerStatus = { - allowRTL: (allowRTL: boolean) => {}, - forceRTL: (forceRTL: boolean) => {}, - setRTL: (setRTL: boolean) => {}, + allowRTL: (allowRTL: boolean) => void, + forceRTL: (forceRTL: boolean) => void, + setPreferredLanguageRTL: (setRTL: boolean) => void, isRTL: boolean }; diff --git a/src/apis/InteractionManager/index.js b/src/apis/InteractionManager/index.js index de006d3f..05a8ce8a 100644 --- a/src/apis/InteractionManager/index.js +++ b/src/apis/InteractionManager/index.js @@ -31,7 +31,7 @@ const InteractionManager = { /** * Notify manager that an interaction has completed. */ - clearInteractionHandle(handle) { + clearInteractionHandle(handle: number) { invariant(!!handle, 'Must provide a handle to clear.'); }, diff --git a/src/apis/Linking/index.js b/src/apis/Linking/index.js index 7c6a24b3..135a8739 100644 --- a/src/apis/Linking/index.js +++ b/src/apis/Linking/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + const Linking = { addEventListener() {}, removeEventListener() {}, @@ -7,7 +11,7 @@ const Linking = { getInitialURL() { return Promise.resolve(''); }, - openURL(url) { + openURL(url: string) { try { iframeOpen(url); return Promise.resolve(); @@ -35,9 +39,10 @@ const iframeOpen = url => { const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; const script = iframeDoc.createElement('script'); + const openerExpression = noOpener ? 'child.opener = null' : ''; script.text = ` window.parent = null; window.top = null; window.frameElement = null; - var child = window.open("${url}"); ${noOpener && 'child.opener = null'}; + var child = window.open("${url}"); ${openerExpression}; `; iframeDoc.body.appendChild(script); document.body.removeChild(iframe); diff --git a/src/apis/NetInfo/index.js b/src/apis/NetInfo/index.js index b2ac9ca4..d7005a05 100644 --- a/src/apis/NetInfo/index.js +++ b/src/apis/NetInfo/index.js @@ -50,7 +50,7 @@ const NetInfo = { connection.removeEventListener(type, handler); }, - fetch(): Promise { + fetch(): Promise { return new Promise((resolve, reject) => { try { resolve(connection.type); @@ -99,7 +99,7 @@ const NetInfo = { connectionListeners.splice(listenerIndex, 1); }, - fetch(): Promise { + fetch(): Promise { return new Promise((resolve, reject) => { try { resolve(window.navigator.onLine); diff --git a/src/apis/Platform/index.js b/src/apis/Platform/index.js index 576a96ec..2a497d9f 100644 --- a/src/apis/Platform/index.js +++ b/src/apis/Platform/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + const Platform = { OS: 'web', select: (obj: Object) => ('web' in obj ? obj.web : obj.default) diff --git a/src/apis/StyleSheet/flattenStyle.js b/src/apis/StyleSheet/flattenStyle.js index 19fe44e1..431e5613 100644 --- a/src/apis/StyleSheet/flattenStyle.js +++ b/src/apis/StyleSheet/flattenStyle.js @@ -12,6 +12,9 @@ import ReactNativePropRegistry from '../../modules/ReactNativePropRegistry'; import invariant from 'fbjs/lib/invariant'; +type Atom = number | boolean | Object | Array; +type StyleObj = Atom; + function getStyle(style) { if (typeof style === 'number') { return ReactNativePropRegistry.getByID(style); @@ -19,7 +22,7 @@ function getStyle(style) { return style; } -function flattenStyle(style) { +function flattenStyle(style: ?StyleObj): ?Object { if (!style) { return undefined; } diff --git a/src/apis/Vibration/index.js b/src/apis/Vibration/index.js index ce83900a..de368f00 100644 --- a/src/apis/Vibration/index.js +++ b/src/apis/Vibration/index.js @@ -1,4 +1,10 @@ -const vibrate = pattern => { +/** + * @flow + */ + +type VibratePattern = number | Array; + +const vibrate = (pattern: VibratePattern) => { if ('vibrate' in window.navigator) { if (typeof pattern === 'number' || Array.isArray(pattern)) { window.navigator.vibrate(pattern); @@ -12,7 +18,7 @@ const Vibration = { cancel() { vibrate(0); }, - vibrate(pattern) { + vibrate(pattern: VibratePattern) { vibrate(pattern); } }; diff --git a/src/components/ActivityIndicator/index.js b/src/components/ActivityIndicator/index.js index 17ff01e5..651fc7ee 100644 --- a/src/components/ActivityIndicator/index.js +++ b/src/components/ActivityIndicator/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import applyNativeMethods from '../../modules/applyNativeMethods'; import StyleSheet from '../../apis/StyleSheet'; import View from '../View'; diff --git a/src/components/Button/index.js b/src/components/Button/index.js index 0b1c43dd..853bc5bb 100644 --- a/src/components/Button/index.js +++ b/src/components/Button/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import ColorPropType from '../../propTypes/ColorPropType'; import StyleSheet from '../../apis/StyleSheet'; import TouchableOpacity from '../Touchable/TouchableOpacity'; diff --git a/src/components/Image/ImageResizeMode.js b/src/components/Image/ImageResizeMode.js index 854fc90d..3c7c2aea 100644 --- a/src/components/Image/ImageResizeMode.js +++ b/src/components/Image/ImageResizeMode.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + const ImageResizeMode = { center: 'center', contain: 'contain', diff --git a/src/components/Image/ImageStylePropTypes.js b/src/components/Image/ImageStylePropTypes.js index ad35c7d7..32288320 100644 --- a/src/components/Image/ImageStylePropTypes.js +++ b/src/components/Image/ImageStylePropTypes.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import BorderPropTypes from '../../propTypes/BorderPropTypes'; import ColorPropType from '../../propTypes/ColorPropType'; import ImageResizeMode from './ImageResizeMode'; diff --git a/src/components/Image/ImageUriCache.js b/src/components/Image/ImageUriCache.js index 84bfc1bd..595c355f 100644 --- a/src/components/Image/ImageUriCache.js +++ b/src/components/Image/ImageUriCache.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + class ImageUriCache { static _maximumEntries: number = 256; static _entries = {}; diff --git a/src/components/Image/index.js b/src/components/Image/index.js index e3528884..9319b30b 100644 --- a/src/components/Image/index.js +++ b/src/components/Image/index.js @@ -1,4 +1,8 @@ /* global window */ +/** + * @flow + */ + import applyNativeMethods from '../../modules/applyNativeMethods'; import createDOMElement from '../../modules/createDOMElement'; import ImageLoader from '../../modules/ImageLoader'; @@ -42,10 +46,12 @@ const resolveAssetDimensions = source => { }; const resolveAssetSource = source => { - return (typeof source === 'object' ? source.uri : source) || null; + return (typeof source === 'object' ? source.uri : source) || ''; }; class Image extends Component { + state: { shouldDisplaySource: boolean }; + static displayName = 'Image'; static propTypes = { @@ -76,6 +82,11 @@ class Image extends Component { static resizeMode = ImageResizeMode; + _imageRequestId = null; + _imageState = null; + _isMounted = false; + _loadRequest = null; + constructor(props, context) { super(props, context); // If an image has been loaded before, render it immediately @@ -84,7 +95,6 @@ class Image extends Component { this.state = { shouldDisplaySource: isPreviouslyLoaded }; this._imageState = getImageState(uri, isPreviouslyLoaded); isPreviouslyLoaded && ImageUriCache.add(uri); - this._isMounted = false; } componentDidMount() { diff --git a/src/components/ProgressBar/index.js b/src/components/ProgressBar/index.js index b43ca5e2..d20d69cc 100644 --- a/src/components/ProgressBar/index.js +++ b/src/components/ProgressBar/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import applyNativeMethods from '../../modules/applyNativeMethods'; import ColorPropType from '../../propTypes/ColorPropType'; import StyleSheet from '../../apis/StyleSheet'; diff --git a/src/components/ScrollView/ScrollViewBase.js b/src/components/ScrollView/ScrollViewBase.js index fa7506d1..78e17b3f 100644 --- a/src/components/ScrollView/ScrollViewBase.js +++ b/src/components/ScrollView/ScrollViewBase.js @@ -67,14 +67,11 @@ export default class ScrollViewBase extends Component { scrollEventThrottle: 0 }; - constructor(props) { - super(props); - this._debouncedOnScrollEnd = debounce(this._handleScrollEnd, 100); - this._state = { isScrolling: false }; - } + _debouncedOnScrollEnd = debounce(this._handleScrollEnd, 100); + _state = { isScrolling: false, scrollLastTick: 0 }; - _handlePreventableScrollEvent = handler => { - return e => { + _handlePreventableScrollEvent = (handler: Function) => { + return (e: Object) => { if (!this.props.scrollEnabled) { e.preventDefault(); } else { @@ -85,7 +82,7 @@ export default class ScrollViewBase extends Component { }; }; - _handleScroll = e => { + _handleScroll = (e: SyntheticEvent) => { e.persist(); e.stopPropagation(); const { scrollEventThrottle } = this.props; @@ -102,12 +99,12 @@ export default class ScrollViewBase extends Component { } }; - _handleScrollStart(e) { + _handleScrollStart(e: Object) { this._state.isScrolling = true; this._state.scrollLastTick = Date.now(); } - _handleScrollTick(e) { + _handleScrollTick(e: Object) { const { onScroll } = this.props; this._state.scrollLastTick = Date.now(); if (onScroll) { @@ -115,7 +112,7 @@ export default class ScrollViewBase extends Component { } } - _handleScrollEnd(e) { + _handleScrollEnd(e: Object) { const { onScroll } = this.props; this._state.isScrolling = false; if (onScroll) { @@ -123,7 +120,7 @@ export default class ScrollViewBase extends Component { } } - _shouldEmitScrollEvent(lastTick, eventThrottle) { + _shouldEmitScrollEvent(lastTick: number, eventThrottle: number) { const timeSinceLastTick = Date.now() - lastTick; return eventThrottle > 0 && timeSinceLastTick >= eventThrottle; } diff --git a/src/components/ScrollView/index.js b/src/components/ScrollView/index.js index cec41207..9452f648 100644 --- a/src/components/ScrollView/index.js +++ b/src/components/ScrollView/index.js @@ -17,7 +17,7 @@ import StyleSheetPropType from '../../propTypes/StyleSheetPropType'; import View from '../View'; import ViewPropTypes from '../View/ViewPropTypes'; import ViewStylePropTypes from '../View/ViewStylePropTypes'; -import React, { Component } from 'react'; +import React from 'react'; import { bool, element, func, number, oneOf } from 'prop-types'; const emptyObject = {}; @@ -54,7 +54,7 @@ const ScrollView = createReactClass({ * implement this method so that they can be composed while providing access * to the underlying scroll responder's methods. */ - getScrollResponder(): Component { + getScrollResponder(): ScrollView { return this; }, diff --git a/src/components/StatusBar/index.js b/src/components/StatusBar/index.js index 71946616..a4dda723 100644 --- a/src/components/StatusBar/index.js +++ b/src/components/StatusBar/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import { Component } from 'react'; class StatusBar extends Component { diff --git a/src/components/Switch/index.js b/src/components/Switch/index.js index 29a6ed44..ebaa5f4c 100644 --- a/src/components/Switch/index.js +++ b/src/components/Switch/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import applyNativeMethods from '../../modules/applyNativeMethods'; import ColorPropType from '../../propTypes/ColorPropType'; import createDOMElement from '../../modules/createDOMElement'; @@ -14,6 +18,8 @@ const thumbDefaultBoxShadow = '0px 1px 3px rgba(0,0,0,0.5)'; const thumbFocusedBoxShadow = `${thumbDefaultBoxShadow}, 0 0 0 10px rgba(0,0,0,0.1)`; class Switch extends PureComponent { + _checkbox: HTMLInputElement; + static displayName = 'Switch'; static propTypes = { diff --git a/src/components/Text/TextStylePropTypes.js b/src/components/Text/TextStylePropTypes.js index 1a391d8f..60e306f8 100644 --- a/src/components/Text/TextStylePropTypes.js +++ b/src/components/Text/TextStylePropTypes.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import ColorPropType from '../../propTypes/ColorPropType'; import ViewStylePropTypes from '../View/ViewStylePropTypes'; import { number, oneOf, oneOfType, shape, string } from 'prop-types'; diff --git a/src/components/Text/index.js b/src/components/Text/index.js index e196c633..94ee4b40 100644 --- a/src/components/Text/index.js +++ b/src/components/Text/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import applyLayout from '../../modules/applyLayout'; import applyNativeMethods from '../../modules/applyNativeMethods'; import BaseComponentPropTypes from '../../propTypes/BaseComponentPropTypes'; diff --git a/src/components/TextInput/TextInputStylePropTypes.js b/src/components/TextInput/TextInputStylePropTypes.js index 7ff62169..780e9e03 100644 --- a/src/components/TextInput/TextInputStylePropTypes.js +++ b/src/components/TextInput/TextInputStylePropTypes.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import TextStylePropTypes from '../Text/TextStylePropTypes'; import { oneOf } from 'prop-types'; diff --git a/src/components/TextInput/index.js b/src/components/TextInput/index.js index 6776ad4a..366fa233 100644 --- a/src/components/TextInput/index.js +++ b/src/components/TextInput/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import applyLayout from '../../modules/applyLayout'; import applyNativeMethods from '../../modules/applyNativeMethods'; import { Component } from 'react'; @@ -50,6 +54,8 @@ const setSelection = (node, selection) => { }; class TextInput extends Component { + _node: HTMLInputElement; + static displayName = 'TextInput'; static propTypes = { diff --git a/src/components/Touchable/TouchableWithoutFeedback.js b/src/components/Touchable/TouchableWithoutFeedback.js index 6fa70660..0df9193d 100644 --- a/src/components/Touchable/TouchableWithoutFeedback.js +++ b/src/components/Touchable/TouchableWithoutFeedback.js @@ -20,7 +20,7 @@ var ensurePositiveDelayProps = require('./ensurePositiveDelayProps'); var warning = require('fbjs/lib/warning'); var StyleSheet = require('../../apis/StyleSheet'); import createReactClass from 'create-react-class'; -import { bool, func, number, string } from 'prop-types'; +import { bool, element, func, number, string } from 'prop-types'; type Event = Object; @@ -42,6 +42,7 @@ const TouchableWithoutFeedback = createReactClass({ accessible: bool, accessibilityLabel: string, accessibilityRole: string, + children: element, /** * If true, disable all interactions for this component. */ diff --git a/src/components/View/ViewPropTypes.js b/src/components/View/ViewPropTypes.js index 6bdd7011..71353603 100644 --- a/src/components/View/ViewPropTypes.js +++ b/src/components/View/ViewPropTypes.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import BaseComponentPropTypes from '../../propTypes/BaseComponentPropTypes'; import EdgeInsetsPropType from '../../propTypes/EdgeInsetsPropType'; import StyleSheetPropType from '../../propTypes/StyleSheetPropType'; diff --git a/src/components/View/ViewStylePropTypes.js b/src/components/View/ViewStylePropTypes.js index 3399b2d7..7ca548c9 100644 --- a/src/components/View/ViewStylePropTypes.js +++ b/src/components/View/ViewStylePropTypes.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import AnimationPropTypes from '../../propTypes/AnimationPropTypes'; import BorderPropTypes from '../../propTypes/BorderPropTypes'; import ColorPropType from '../../propTypes/ColorPropType'; diff --git a/src/components/View/index.js b/src/components/View/index.js index f00dc098..b9163c02 100644 --- a/src/components/View/index.js +++ b/src/components/View/index.js @@ -1,3 +1,7 @@ +/** + * @flow + */ + import AccessibilityUtil from '../../modules/AccessibilityUtil'; import applyLayout from '../../modules/applyLayout'; import applyNativeMethods from '../../modules/applyNativeMethods'; diff --git a/src/modules/NativeMethodsMixin/index.js b/src/modules/NativeMethodsMixin/index.js index 8f814ad6..8c1a53d3 100644 --- a/src/modules/NativeMethodsMixin/index.js +++ b/src/modules/NativeMethodsMixin/index.js @@ -15,6 +15,29 @@ import UIManager from '../../apis/UIManager'; const hyphenPattern = /-([a-z])/g; const toCamelCase = str => str.replace(hyphenPattern, m => m[1].toUpperCase()); +type MeasureOnSuccessCallback = ( + x: number, + y: number, + width: number, + height: number, + pageX: number, + pageY: number +) => void; + +type MeasureInWindowOnSuccessCallback = ( + x: number, + y: number, + width: number, + height: number +) => void; + +type MeasureLayoutOnSuccessCallback = ( + left: number, + top: number, + width: number, + height: number +) => void; + const NativeMethodsMixin = { /** * Removes focus from an input or view. This is the opposite of `focus()`. @@ -34,7 +57,7 @@ const NativeMethodsMixin = { /** * Determines the position and dimensions of the view */ - measure(callback) { + measure(callback: MeasureOnSuccessCallback) { UIManager.measure(findNodeHandle(this), callback); }, @@ -53,14 +76,18 @@ const NativeMethodsMixin = { * Note that these measurements are not available until after the rendering * has been completed. */ - measureInWindow(callback) { + measureInWindow(callback: MeasureInWindowOnSuccessCallback) { UIManager.measureInWindow(findNodeHandle(this), callback); }, /** * Measures the view relative to another view (usually an ancestor) */ - measureLayout(relativeToNativeNode, onSuccess, onFail) { + measureLayout( + relativeToNativeNode: Object, + onSuccess: MeasureLayoutOnSuccessCallback, + onFail: () => void + ) { UIManager.measureLayout(findNodeHandle(this), relativeToNativeNode, onFail, onSuccess); }, diff --git a/src/modules/applyLayout/index.js b/src/modules/applyLayout/index.js index 73ff8acc..62c8f662 100644 --- a/src/modules/applyLayout/index.js +++ b/src/modules/applyLayout/index.js @@ -35,7 +35,7 @@ const safeOverride = (original, next) => { return next; }; -const applyLayout = Component => { +const applyLayout = (Component: ReactClass) => { const componentDidMount = Component.prototype.componentDidMount; const componentDidUpdate = Component.prototype.componentDidUpdate; const componentWillUnmount = Component.prototype.componentWillUnmount; diff --git a/src/modules/applyNativeMethods/index.js b/src/modules/applyNativeMethods/index.js index 6d13de63..2df551bc 100644 --- a/src/modules/applyNativeMethods/index.js +++ b/src/modules/applyNativeMethods/index.js @@ -7,7 +7,7 @@ import NativeMethodsMixin from '../NativeMethodsMixin'; -const applyNativeMethods = Component => { +const applyNativeMethods = (Component: ReactClass) => { Object.keys(NativeMethodsMixin).forEach(method => { if (!Component.prototype[method]) { Component.prototype[method] = NativeMethodsMixin[method]; diff --git a/src/propTypes/EdgeInsetsPropType.js b/src/propTypes/EdgeInsetsPropType.js index a9f72523..aaf437b7 100644 --- a/src/propTypes/EdgeInsetsPropType.js +++ b/src/propTypes/EdgeInsetsPropType.js @@ -10,11 +10,18 @@ * @providesModule EdgeInsetsPropType * @flow */ -'use strict'; +import createStrictShapeTypeChecker from './createStrictShapeTypeChecker'; import { number } from 'prop-types'; -var EdgeInsetsPropType = require('./createStrictShapeTypeChecker')({ +export type EdgeInsetsProp = { + top: number, + left: number, + bottom: number, + right: number +}; + +const EdgeInsetsPropType = createStrictShapeTypeChecker({ top: number, left: number, bottom: number, diff --git a/src/propTypes/StyleSheetPropType.js b/src/propTypes/StyleSheetPropType.js index 1d4e8eba..4009dbd8 100644 --- a/src/propTypes/StyleSheetPropType.js +++ b/src/propTypes/StyleSheetPropType.js @@ -5,18 +5,20 @@ * @flow */ -module.exports = function StyleSheetPropType(shape) { +function StyleSheetPropType(shape: { [key: string]: ReactPropsCheckType }): ReactPropsCheckType { const createStrictShapeTypeChecker = require('./createStrictShapeTypeChecker'); const StyleSheet = require('../apis/StyleSheet'); const shapePropType = createStrictShapeTypeChecker(shape); - return function(props, propName, componentName, location?) { + return function(props, propName, componentName, location?, ...rest) { let newProps = props; if (props[propName]) { // Just make a dummy prop object with only the flattened style newProps = {}; newProps[propName] = StyleSheet.flatten(props[propName]); } - return shapePropType(newProps, propName, componentName, location); + return shapePropType(newProps, propName, componentName, location, ...rest); }; -}; +} + +module.exports = StyleSheetPropType; diff --git a/types/fbjs.js b/types/fbjs.js index 37248484..45cbe8ab 100644 --- a/types/fbjs.js +++ b/types/fbjs.js @@ -8,11 +8,7 @@ */ declare module 'fbjs/lib/invariant' { - declare function exports( - condition: any, - message: string, - ...args: Array - ): void; + declare function exports(condition: any, message: string, ...args: Array): void; } declare module 'fbjs/lib/nullthrows' {