Skip to content

Commit

Permalink
Treat createClass component propTypes as annots
Browse files Browse the repository at this point in the history
Summary:
Flow has support for defining components using createClass, which is long
deprecated but still has some uses in our codebase. Using createClass,
programmers declare the expected props of their component by defining an object
value, which Flow converts into an annotation.

The exact method for this conversion is not relevant here. The important part is
that we have values which should be treated more like annotations. This diff
ensures that the reasons for these types have an associated "annot location."
This results in better error messages, as can be seen in the changed test
output.

Reviewed By: jbrown215

Differential Revision: D21754471

fbshipit-source-id: 2fbc40a982963facd74d1a2cf5e33d65c31a36b8
  • Loading branch information
samwgoldman authored and facebook-github-bot committed Jun 4, 2020
1 parent 877bef0 commit f4a0fca
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 245 deletions.
2 changes: 1 addition & 1 deletion src/typing/react_kit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ module Kit (Flow : Flow_common.S) : REACT = struct
let coerce_prop_type = function
| CustomFunT (reason, ReactPropType (PropType.Primitive (required, t))) ->
let loc = aloc_of_reason reason in
Ok (required, reposition cx ~trace loc t)
Ok (required, reposition cx ~trace ~annot_loc:loc loc t)
| DefT (reason, _, FunT _) as t ->
rec_flow_t
~use_op:unknown_use
Expand Down
20 changes: 10 additions & 10 deletions tests/getters_and_setters/getters_and_setters.exp
Original file line number Diff line number Diff line change
Expand Up @@ -471,27 +471,27 @@ Error --------------------------------------------------------------------------
Cannot create `Example` element because string [1] is incompatible with number [2] in property `a`. [incompatible-type]

react.js:17:13
17| (<Example a="bad" />); // error: number ~> string
^^^^^ [1]
17| (<Example a="bad" />); // error: number ~> string
^^^^^ [1]

References:
<BUILTINS>/react.js:488:36
488| number: React$PropType$Primitive<number>,
^^^^^^ [2]
react.js:9:22
9| get a() { return React.PropTypes.number.isRequired; },
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2]


Error --------------------------------------------------------------------------------------------------- react.js:18:20

Cannot create `Example` element because number [1] is incompatible with string [2] in property `c`. [incompatible-type]

react.js:18:20
18| (<Example a={0} c={0} />); // error: number ~> string
^ [1]
18| (<Example a={0} c={0} />); // error: number ~> string
^ [1]

References:
<BUILTINS>/react.js:490:36
490| string: React$PropType$Primitive<string>,
^^^^^^ [2]
react.js:11:8
11| c: React.PropTypes.string,
^^^^^^^^^^^^^^^^^^^^^^ [2]


Error ------------------------------------------------------------------------------------------------- variance.js:21:2
Expand Down
176 changes: 88 additions & 88 deletions tests/new_react/new_react.exp
Original file line number Diff line number Diff line change
Expand Up @@ -218,16 +218,16 @@ Error --------------------------------------------------------------------------
Cannot assign `this.props.x` to `_` because number [1] is incompatible with string [2]. [incompatible-type]

classes.js:57:21
57| var _: string = this.props.x;
^^^^^^^^^^^^
57| var _: string = this.props.x;
^^^^^^^^^^^^

References:
<BUILTINS>/react.js:488:36
488| number: React$PropType$Primitive<number>,
^^^^^^ [1]
classes.js:47:8
47| x: React.PropTypes.number.isRequired
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [1]
classes.js:57:12
57| var _: string = this.props.x;
^^^^^^ [2]
57| var _: string = this.props.x;
^^^^^^ [2]


Error ------------------------------------------------------------------------------------------------- classes.js:64:11
Expand Down Expand Up @@ -469,50 +469,50 @@ Error --------------------------------------------------------------------------
Cannot assign `this.props.z` to `qux` because number [1] is incompatible with string [2]. [incompatible-type]

new_react.js:19:27
19| var qux: string = this.props.z;
^^^^^^^^^^^^
19| var qux: string = this.props.z;
^^^^^^^^^^^^

References:
<BUILTINS>/react.js:488:36
488| number: React$PropType$Primitive<number>,
^^^^^^ [1]
new_react.js:8:12
8| z: React.PropTypes.number
^^^^^^^^^^^^^^^^^^^^^^ [1]
new_react.js:19:18
19| var qux: string = this.props.z;
^^^^^^ [2]
19| var qux: string = this.props.z;
^^^^^^ [2]


Error ----------------------------------------------------------------------------------------------- new_react.js:19:27

Cannot assign `this.props.z` to `qux` because undefined [1] is incompatible with string [2]. [incompatible-type]

new_react.js:19:27
19| var qux: string = this.props.z;
^^^^^^^^^^^^
19| var qux: string = this.props.z;
^^^^^^^^^^^^

References:
<BUILTINS>/react.js:488:36
488| number: React$PropType$Primitive<number>,
^^^^^^ [1]
new_react.js:8:12
8| z: React.PropTypes.number
^^^^^^^^^^^^^^^^^^^^^^ [1]
new_react.js:19:18
19| var qux: string = this.props.z;
^^^^^^ [2]
19| var qux: string = this.props.z;
^^^^^^ [2]


Error ----------------------------------------------------------------------------------------------- new_react.js:20:24

Cannot assign `this.props.x` to `w` because string [1] is incompatible with number [2]. [incompatible-type]

new_react.js:20:24
20| var w:number = this.props.x;
^^^^^^^^^^^^
20| var w:number = this.props.x;
^^^^^^^^^^^^

References:
<BUILTINS>/react.js:490:36
490| string: React$PropType$Primitive<string>,
^^^^^^ [1]
new_react.js:6:12
6| x: React.PropTypes.string.isRequired,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [1]
new_react.js:20:15
20| var w:number = this.props.x;
^^^^^^ [2]
20| var w:number = this.props.x;
^^^^^^ [2]


Error ----------------------------------------------------------------------------------------------- new_react.js:21:22
Expand All @@ -521,27 +521,27 @@ Cannot get `this.props.y[0]` because an index signature declaring the expected k
undefined [1]. [incompatible-use]

new_react.js:21:22
21| this.props.y[0];
^
21| this.props.y[0];
^

References:
<BUILTINS>/react.js:485:35
485| array: React$PropType$Primitive<Array<any>>,
^^^^^^^^^^ [1]
new_react.js:7:12
7| y: React.PropTypes.array,
^^^^^^^^^^^^^^^^^^^^^ [1]


Error ----------------------------------------------------------------------------------------------- new_react.js:29:23

Cannot create `C` element because number [1] is incompatible with string [2] in property `x`. [incompatible-type]

new_react.js:29:23
29| var element = <C x = {0}/>;
^ [1]
29| var element = <C x = {0}/>;
^ [1]

References:
<BUILTINS>/react.js:490:36
490| string: React$PropType$Primitive<string>,
^^^^^^ [2]
new_react.js:6:12
6| x: React.PropTypes.string.isRequired,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2]


Error ----------------------------------------------------------------------------------------------- new_react.js:30:17
Expand Down Expand Up @@ -703,33 +703,33 @@ Error --------------------------------------------------------------------------
Cannot assign `this.props.x` to `a` because string [1] is incompatible with number [2]. [incompatible-type]

props.js:14:25
14| var a: number = this.props.x; // error
^^^^^^^^^^^^
14| var a: number = this.props.x; // error
^^^^^^^^^^^^

References:
<BUILTINS>/react.js:490:36
490| string: React$PropType$Primitive<string>,
^^^^^^ [1]
props.js:5:12
5| x: React.PropTypes.string,
^^^^^^^^^^^^^^^^^^^^^^ [1]
props.js:14:16
14| var a: number = this.props.x; // error
^^^^^^ [2]
14| var a: number = this.props.x; // error
^^^^^^ [2]


Error --------------------------------------------------------------------------------------------------- props.js:14:25

Cannot assign `this.props.x` to `a` because undefined [1] is incompatible with number [2]. [incompatible-type]

props.js:14:25
14| var a: number = this.props.x; // error
^^^^^^^^^^^^
14| var a: number = this.props.x; // error
^^^^^^^^^^^^

References:
<BUILTINS>/react.js:490:36
490| string: React$PropType$Primitive<string>,
^^^^^^ [1]
props.js:5:12
5| x: React.PropTypes.string,
^^^^^^^^^^^^^^^^^^^^^^ [1]
props.js:14:16
14| var a: number = this.props.x; // error
^^^^^^ [2]
14| var a: number = this.props.x; // error
^^^^^^ [2]


Error --------------------------------------------------------------------------------------------------- props.js:15:36
Expand All @@ -755,33 +755,33 @@ Error --------------------------------------------------------------------------
Cannot assign `this.props.z` to `c` because number [1] is incompatible with string [2]. [incompatible-type]

props.js:16:25
16| var c: string = this.props.z; // error
^^^^^^^^^^^^
16| var c: string = this.props.z; // error
^^^^^^^^^^^^

References:
<BUILTINS>/react.js:488:36
488| number: React$PropType$Primitive<number>,
^^^^^^ [1]
props.js:6:12
6| z: React.PropTypes.number
^^^^^^^^^^^^^^^^^^^^^^ [1]
props.js:16:16
16| var c: string = this.props.z; // error
^^^^^^ [2]
16| var c: string = this.props.z; // error
^^^^^^ [2]


Error --------------------------------------------------------------------------------------------------- props.js:16:25

Cannot assign `this.props.z` to `c` because undefined [1] is incompatible with string [2]. [incompatible-type]

props.js:16:25
16| var c: string = this.props.z; // error
^^^^^^^^^^^^
16| var c: string = this.props.z; // error
^^^^^^^^^^^^

References:
<BUILTINS>/react.js:488:36
488| number: React$PropType$Primitive<number>,
^^^^^^ [1]
props.js:6:12
6| z: React.PropTypes.number
^^^^^^^^^^^^^^^^^^^^^^ [1]
props.js:16:16
16| var c: string = this.props.z; // error
^^^^^^ [2]
16| var c: string = this.props.z; // error
^^^^^^ [2]


Error --------------------------------------------------------------------------------------------------- props.js:20:29
Expand All @@ -790,13 +790,13 @@ Cannot create `TestProps` element because boolean [1] is incompatible with strin
[incompatible-type]

props.js:20:29
20| var element = <TestProps x={false} y={false} z={false} />; // 3 errors
^^^^^ [1]
20| var element = <TestProps x={false} y={false} z={false} />; // 3 errors
^^^^^ [1]

References:
<BUILTINS>/react.js:490:36
490| string: React$PropType$Primitive<string>,
^^^^^^ [2]
props.js:5:12
5| x: React.PropTypes.string,
^^^^^^^^^^^^^^^^^^^^^^ [2]


Error --------------------------------------------------------------------------------------------------- props.js:20:49
Expand All @@ -805,13 +805,13 @@ Cannot create `TestProps` element because boolean [1] is incompatible with numbe
[incompatible-type]

props.js:20:49
20| var element = <TestProps x={false} y={false} z={false} />; // 3 errors
^^^^^ [1]
20| var element = <TestProps x={false} y={false} z={false} />; // 3 errors
^^^^^ [1]

References:
<BUILTINS>/react.js:488:36
488| number: React$PropType$Primitive<number>,
^^^^^^ [2]
props.js:6:12
6| z: React.PropTypes.number
^^^^^^^^^^^^^^^^^^^^^^ [2]


Error ---------------------------------------------------------------------------------------------------- props.js:27:2
Expand Down Expand Up @@ -858,30 +858,30 @@ Error --------------------------------------------------------------------------
Cannot create `C` element because number [1] is incompatible with string [2] in property `bar`. [incompatible-type]

props2.js:15:17
15| return <C {...this.state} foo = {0} />;
^
15| return <C {...this.state} foo = {0} />;
^

References:
props2.js:9:41
9| getInitialState: function(): { bar: number } {
^^^^^^ [1]
<BUILTINS>/react.js:490:36
490| string: React$PropType$Primitive<string>,
^^^^^^ [2]
9| getInitialState: function(): { bar: number } {
^^^^^^ [1]
props2.js:5:14
5| bar: React.PropTypes.string.isRequired,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2]


Error -------------------------------------------------------------------------------------------------- props2.js:15:42

Cannot create `C` element because number [1] is incompatible with string [2] in property `foo`. [incompatible-type]

props2.js:15:42
15| return <C {...this.state} foo = {0} />;
^ [1]
15| return <C {...this.state} foo = {0} />;
^ [1]

References:
<BUILTINS>/react.js:490:36
490| string: React$PropType$Primitive<string>,
^^^^^^ [2]
props2.js:4:14
4| foo: React.PropTypes.string.isRequired,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2]


Error -------------------------------------------------------------------------------------------------- props3.js:49:32
Expand Down
Loading

0 comments on commit f4a0fca

Please sign in to comment.