Skip to content

[FlowCleanup] InspectorPanel -> Delete PropTypes #21392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
60 changes: 41 additions & 19 deletions Libraries/Inspector/InspectorPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,43 @@ const ElementProperties = require('ElementProperties');
const NetworkOverlay = require('NetworkOverlay');
const PerformanceOverlay = require('PerformanceOverlay');
const React = require('React');
const PropTypes = require('prop-types');
const ScrollView = require('ScrollView');
const StyleSheet = require('StyleSheet');
const Text = require('Text');
const TouchableHighlight = require('TouchableHighlight');
const View = require('View');

class InspectorPanel extends React.Component<$FlowFixMeProps> {
import type {ViewStyleProp} from 'StyleSheet';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear type. Using any, Object, Function, $Subtype<...>, or $Supertype<...> types is not safe! (unclear-type)


type Props = $ReadOnly<{|
devtoolsIsOpen?: ?boolean,
inspecting?: ?boolean,
Copy link
Contributor Author

@dkaushik95 dkaushik95 Sep 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle CI errors indicate that we need to strict type it rather than ?boolean. Do we want strict type checking or nullable type checking? or maybe both. I think this applies to all the boolean values when we are doing:

if(value) then something

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the following work?

  if (value === true) {
    // stuff
  }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. But these props can be either boolean or undefined. I don't know how to write for both? ?boolean should work, but I get this error:

Sketchy null check on boolean [1] which is potentially false. Perhaps you meant to check for null or undefined [2]?
(`sketchy-null-bool`)`

Copy link
Contributor

@RSNara RSNara Sep 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... There's only one use of <InspectorPanel> in the codebase:

<InspectorPanel
  devtoolsIsOpen={!!this.state.devtoolsAgent}
  inspecting={this.state.inspecting}
  perfing={this.state.perfing}
  setPerfing={this.setPerfing.bind(this)}
  setInspecting={this.setInspecting.bind(this)}
  inspected={this.state.inspected}
  hierarchy={this.state.hierarchy}
  selection={this.state.selection}
  setSelection={this.setSelection.bind(this)}
  touchTargeting={Touchable.TOUCH_TARGET_DEBUG}
  setTouchTargeting={this.setTouchTargeting.bind(this)}
  networking={this.state.networking}
  setNetworking={this.setNetworking.bind(this)}
/>

Lets make the inspecting, setInspecting, perfing, setPerfing, selection, setSelection props non-optional. That should fix our problems.

setInspecting?: ?(val: boolean) => void,
perfing?: ?boolean,
setPerfing?: ?(val: boolean) => void,
touchTargeting?: ?boolean,
setTouchTargeting?: ?(val: boolean) => void,
networking?: ?boolean,
setNetworking?: ?(val: boolean) => void,
hierarchy?: any,
selection?: ?number,
setSelection?: number => mixed,
inspected?: ?{
style?: ?ViewStyleProp,
frame?: ?{
top?: ?number,
left?: ?number,
width?: ?number,
height: ?number,
},
source?: ?{
fileName?: string,
lineNumber?: number,
},
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be more strict and use exact object types here, so:

  inspected?: ?{|
    style?: ?ViewStyleProp,
    frame?: ?{|
      top?: ?number,
      left?: ?number,
      width?: ?number,
      height: ?number,
    |},
    source?: ?{|
      fileName?: string,
      lineNumber?: number,
    |},
  |},

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. Also, I found these types from other components. So should we export these types on those components and reference them here? There are many components in Inspector which needs to be converted to flow types.

Copy link
Contributor

@RSNara RSNara Sep 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that sounds like a great idea! I can see there being an InspectorTypes module under Libraries/Inspector that contains shared types for the modules in that folder. But I think it may be too much to make that refactor in this diff.

Would you like to tackle this in another PR? For now, we can just copy-paste the frame type here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I'll finish up with this today and work on the Inspector folder next week.

|}>;

class InspectorPanel extends React.Component<Props> {
renderWaiting() {
if (this.props.inspecting) {
return (
Expand Down Expand Up @@ -57,22 +86,22 @@ class InspectorPanel extends React.Component<$FlowFixMeProps> {
<View style={styles.container}>
{!this.props.devtoolsIsOpen && contents}
<View style={styles.buttonRow}>
<Button
<InspectorPanelButton
title={'Inspect'}
pressed={this.props.inspecting}
onClick={this.props.setInspecting}
/>
<Button
<InspectorPanelButton
title={'Perf'}
pressed={this.props.perfing}
onClick={this.props.setPerfing}
/>
<Button
<InspectorPanelButton
title={'Network'}
pressed={this.props.networking}
onClick={this.props.setNetworking}
/>
<Button
<InspectorPanelButton
title={'Touchables'}
pressed={this.props.touchTargeting}
onClick={this.props.setTouchTargeting}
Expand All @@ -83,20 +112,13 @@ class InspectorPanel extends React.Component<$FlowFixMeProps> {
}
}

InspectorPanel.propTypes = {
devtoolsIsOpen: PropTypes.bool,
inspecting: PropTypes.bool,
setInspecting: PropTypes.func,
inspected: PropTypes.object,
perfing: PropTypes.bool,
setPerfing: PropTypes.func,
touchTargeting: PropTypes.bool,
setTouchTargeting: PropTypes.func,
networking: PropTypes.bool,
setNetworking: PropTypes.func,
};
type InspectorPanelButtonProps = $ReadOnly<{|
onClick?: ?Function,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RSNara I need a similar params/return type here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. This should also take the same signature:

onClick?: ?(val: boolean) => void

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I think about it more, a lot of these types are unnecessarily optional. For example, I think onClick should not be optional, since we assume (in the implementation of this component) that it's a function. Do you mind making these optional properties, that don't need to be optional, non-optional?

pressed?: ?boolean,
title?: ?string,
|}>;

class Button extends React.Component<$FlowFixMeProps> {
class InspectorPanelButton extends React.Component<InspectorPanelButtonProps> {
render() {
return (
<TouchableHighlight
Expand Down