From 0eff6fc9bdd5fac5f0960395d972f4b3144fc2a2 Mon Sep 17 00:00:00 2001 From: Moti Zilberman Date: Mon, 22 Oct 2018 09:11:41 +0100 Subject: [PATCH] Add definition for React.forwardRef() Closes #6103 --- lib/react.js | 4 + .../getters_and_setters.exp | 8 +- tests/new_react/new_react.exp | 46 ++--- tests/react/react.exp | 176 +++++++++--------- tests/react_children/react_children.exp | 12 +- tests/react_forward_ref/.flowconfig | 2 + tests/react_forward_ref/react_forward_ref.exp | 50 +++++ tests/react_forward_ref/test.js | 17 ++ tests/react_imports/react_imports.exp | 119 ++++++------ tests/react_jsx/react_jsx.exp | 28 +-- tests/type-at-pos/type-at-pos.exp | 6 +- 11 files changed, 272 insertions(+), 196 deletions(-) create mode 100644 tests/react_forward_ref/.flowconfig create mode 100644 tests/react_forward_ref/react_forward_ref.exp create mode 100644 tests/react_forward_ref/test.js diff --git a/lib/react.js b/lib/react.js index c59257db22d..7c138ba2591 100644 --- a/lib/react.js +++ b/lib/react.js @@ -230,6 +230,9 @@ declare module react { ): React$ElementFactory; declare export function createRef( ): {current: null | React$ElementRef}; + declare export function forwardRef( + render: (props: Props, ref: React$Ref) => React$Node + ): React$ComponentType; declare export function isValidElement(element: any): boolean; @@ -279,6 +282,7 @@ declare module react { +cloneElement: typeof cloneElement, +createFactory: typeof createFactory, +createRef: typeof createRef, + +forwardRef: typeof forwardRef, +isValidElement: typeof isValidElement, +Component: typeof Component, +PureComponent: typeof PureComponent, diff --git a/tests/getters_and_setters/getters_and_setters.exp b/tests/getters_and_setters/getters_and_setters.exp index 358921c55d0..2431e5448c0 100644 --- a/tests/getters_and_setters/getters_and_setters.exp +++ b/tests/getters_and_setters/getters_and_setters.exp @@ -465,8 +465,8 @@ References: react.js:17:13 17| (); // error: number ~> string ^^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -482,8 +482,8 @@ References: react.js:18:20 18| (); // error: number ~> string ^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] diff --git a/tests/new_react/new_react.exp b/tests/new_react/new_react.exp index fb89c600a97..d3b533c2dfb 100644 --- a/tests/new_react/new_react.exp +++ b/tests/new_react/new_react.exp @@ -189,8 +189,8 @@ Cannot assign `this.props.x` to `_` because number [1] is incompatible with stri ^^^^^^^^^^^^ References: - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [1] classes.js:57:12 57| var _: string = this.props.x; @@ -388,8 +388,8 @@ Cannot assign `this.props.z` to `qux` because: ^^^^^^^^^^^^ References: - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [1] new_react.js:19:18 19| var qux: string = this.props.z; @@ -405,8 +405,8 @@ Cannot assign `this.props.x` to `w` because string [1] is incompatible with numb ^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] new_react.js:20:15 20| var w:number = this.props.x; @@ -439,8 +439,8 @@ References: new_react.js:29:23 29| var element = ; ^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] @@ -545,8 +545,8 @@ Cannot assign `this.props.x` to `a` because: ^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] props.js:14:16 14| var a: number = this.props.x; // error @@ -582,8 +582,8 @@ Cannot assign `this.props.z` to `c` because: ^^^^^^^^^^^^ References: - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [1] props.js:16:16 16| var c: string = this.props.z; // error @@ -604,14 +604,14 @@ References: props.js:20:29 20| var element = ; // 3 errors ^^^^^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] props.js:20:49 20| var element = ; // 3 errors ^^^^^ [3] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [4] @@ -668,8 +668,8 @@ References: props2.js:9:41 9| getInitialState: function(): { bar: number } { ^^^^^^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] props2.js:15:42 15| return ; @@ -700,12 +700,12 @@ Cannot get `React.PropTypes.string.inRequired` because property `inRequired` is ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ References: - /react.js:302:39 + /react.js:306:39 v - 302| type ReactPropsChainableTypeChecker = { - 303| isRequired: ReactPropsCheckType; - 304| (props: any, propName: string, componentName: string, href?: string): ?Error; - 305| }; + 306| type ReactPropsChainableTypeChecker = { + 307| isRequired: ReactPropsCheckType; + 308| (props: any, propName: string, componentName: string, href?: string): ?Error; + 309| }; ^ [1] diff --git a/tests/react/react.exp b/tests/react/react.exp index 98c22721a48..f23c7fb1510 100644 --- a/tests/react/react.exp +++ b/tests/react/react.exp @@ -21,8 +21,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:7:22 7| (this.props.foo: empty); // error: string ~> empty @@ -38,8 +38,8 @@ Cannot cast `this.props.bar` to empty because number [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [1] create_class.js:8:22 8| (this.props.bar: empty); // error: number ~> empty @@ -192,8 +192,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:117:22 117| (this.props.foo: empty); // string ~> empty @@ -209,8 +209,8 @@ Cannot cast `this.state.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:118:22 118| (this.state.foo: empty); // string ~> empty @@ -226,8 +226,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:133:22 133| (this.props.foo: empty); // string ~> empty @@ -243,8 +243,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:137:22 137| (this.props.foo: empty); // string ~> empty @@ -260,8 +260,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:141:22 141| (this.props.foo: empty); // string ~> empty @@ -277,8 +277,8 @@ Cannot cast `nextProps.foo` to empty because string [1] is incompatible with emp ^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:142:21 142| (nextProps.foo: empty); // string ~> empty @@ -294,8 +294,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:146:22 146| (this.props.foo: empty); // string ~> empty @@ -328,8 +328,8 @@ Cannot cast `nextProps.foo` to empty because string [1] is incompatible with emp ^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:148:21 148| (nextProps.foo: empty); // string ~> empty @@ -376,8 +376,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:153:22 153| (this.props.foo: empty); // string ~> empty @@ -410,8 +410,8 @@ Cannot cast `nextProps.foo` to empty because string [1] is incompatible with emp ^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:155:21 155| (nextProps.foo: empty); // string ~> empty @@ -444,8 +444,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:160:22 160| (this.props.foo: empty); // string ~> empty @@ -478,8 +478,8 @@ Cannot cast `nextProps.foo` to empty because string [1] is incompatible with emp ^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:162:21 162| (nextProps.foo: empty); // string ~> empty @@ -512,8 +512,8 @@ Cannot cast `this.props.foo` to empty because string [1] is incompatible with em ^^^^^^^^^^^^^^ References: - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [1] create_class.js:167:22 167| (this.props.foo: empty); // string ~> empty @@ -1845,8 +1845,8 @@ References: jsx_spread.js:10:19 10| var props = {bar: 42}; ^^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] @@ -1959,8 +1959,8 @@ References: proptype_arrayOf.js:15:45 15| var fail_mistyped_elems = ^^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -1976,8 +1976,8 @@ References: proptype_arrayOf.js:20:36 20| var todo_required = ^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -1994,8 +1994,8 @@ References: proptype_arrayOf.js:30:25 30| (); // error: string ~> number ^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -2033,8 +2033,8 @@ Cannot cast `propName` to empty because string [1] is incompatible with empty [2 ^^^^^^^^ References: - /react.js:298:13 - 298| propName: string, + /react.js:302:13 + 302| propName: string, ^^^^^^ [1] proptype_custom_validator.js:8:18 8| (propName: empty); // error: propName is a string @@ -2050,8 +2050,8 @@ Cannot cast `componentName` to empty because string [1] is incompatible with emp ^^^^^^^^^^^^^ References: - /react.js:299:18 - 299| componentName: string, + /react.js:303:18 + 303| componentName: string, ^^^^^^ [1] proptype_custom_validator.js:9:23 9| (componentName: empty); // error: componentName is a string @@ -2069,8 +2069,8 @@ Cannot cast `href` to empty because: ^^^^ References: - /react.js:300:10 - 300| href?: string) => ?Error; + /react.js:304:10 + 304| href?: string) => ?Error; ^^^^^^ [1] proptype_custom_validator.js:10:14 10| (href: empty); // error: href is an optional string @@ -2089,8 +2089,8 @@ References: proptype_custom_validator.js:11:18 11| return (0: mixed); // error: should return ?Error ^^^^^ [1] - /react.js:300:22 - 300| href?: string) => ?Error; + /react.js:304:22 + 304| href?: string) => ?Error; ^^^^^ [2] @@ -2106,8 +2106,8 @@ References: proptype_func.js:14:36 14| var fail_mistyped = ^ [1] - /react.js:325:34 - 325| func: React$PropType$Primitive; + /react.js:329:34 + 329| func: React$PropType$Primitive; ^^^^^^^^ [2] @@ -2165,8 +2165,8 @@ References: proptype_object.js:13:38 13| var fail_mistyped = ^ [1] - /react.js:327:36 - 327| object: React$PropType$Primitive; + /react.js:331:36 + 331| object: React$PropType$Primitive; ^^^^^^ [2] @@ -2217,8 +2217,8 @@ References: proptype_objectOf.js:15:47 15| var fail_mistyped_props = ^^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -2234,8 +2234,8 @@ References: proptype_objectOf.js:20:38 20| var todo_required = ^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -2251,8 +2251,8 @@ References: proptype_objectOf.js:30:27 30| (); // error: string ~> number ^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -2427,11 +2427,11 @@ References: proptype_oneOfType.js:24:32 24| var fail_bool = ; ^^^^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [3] @@ -2449,11 +2449,11 @@ References: proptype_oneOfType.js:29:36 29| var todo_required = ; ^^^^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [3] @@ -2469,8 +2469,8 @@ References: proptype_oneOfType.js:41:22 41| (); // error: number ~> string ^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] @@ -2552,14 +2552,14 @@ Cannot cast `React.PropTypes.arrayOf` to `NoFun` because: ^^^^^^^^^^^^^^^^^^^^^^^ References: - /react.js:308:17 - 308| (typeChecker: ReactPropsCheckType) => ReactPropsChainableTypeChecker; + /react.js:312:17 + 312| (typeChecker: ReactPropsCheckType) => ReactPropsChainableTypeChecker; ^^^^^^^^^^^^^^^^^^^ [1] proptypes_builtins.js:3:14 3| type NoFun = mixed => empty; ^^^^^ [2] - /react.js:308:41 - 308| (typeChecker: ReactPropsCheckType) => ReactPropsChainableTypeChecker; + /react.js:312:41 + 312| (typeChecker: ReactPropsCheckType) => ReactPropsChainableTypeChecker; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [3] proptypes_builtins.js:3:23 3| type NoFun = mixed => empty; @@ -2576,8 +2576,8 @@ empty [2] in the return value. ^^^^^^^^^^^^^^^^^^^^^^^^^^ References: - /react.js:310:27 - 310| (expectedClass: any) => ReactPropsChainableTypeChecker; + /react.js:314:27 + 314| (expectedClass: any) => ReactPropsChainableTypeChecker; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [1] proptypes_builtins.js:3:23 3| type NoFun = mixed => empty; @@ -2595,14 +2595,14 @@ Cannot cast `React.PropTypes.objectOf` to `NoFun` because: ^^^^^^^^^^^^^^^^^^^^^^^^ References: - /react.js:312:17 - 312| (typeChecker: ReactPropsCheckType) => ReactPropsChainableTypeChecker; + /react.js:316:17 + 316| (typeChecker: ReactPropsCheckType) => ReactPropsChainableTypeChecker; ^^^^^^^^^^^^^^^^^^^ [1] proptypes_builtins.js:3:14 3| type NoFun = mixed => empty; ^^^^^ [2] - /react.js:312:41 - 312| (typeChecker: ReactPropsCheckType) => ReactPropsChainableTypeChecker; + /react.js:316:41 + 316| (typeChecker: ReactPropsCheckType) => ReactPropsChainableTypeChecker; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [3] proptypes_builtins.js:3:23 3| type NoFun = mixed => empty; @@ -2620,14 +2620,14 @@ Cannot cast `React.PropTypes.oneOf` to `NoFun` because: ^^^^^^^^^^^^^^^^^^^^^ References: - /react.js:314:20 - 314| (expectedValues: Array) => ReactPropsChainableTypeChecker; + /react.js:318:20 + 318| (expectedValues: Array) => ReactPropsChainableTypeChecker; ^^^^^^^^^^ [1] proptypes_builtins.js:3:14 3| type NoFun = mixed => empty; ^^^^^ [2] - /react.js:314:35 - 314| (expectedValues: Array) => ReactPropsChainableTypeChecker; + /react.js:318:35 + 318| (expectedValues: Array) => ReactPropsChainableTypeChecker; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [3] proptypes_builtins.js:3:23 3| type NoFun = mixed => empty; @@ -2645,14 +2645,14 @@ Cannot cast `React.PropTypes.oneOfType` to `NoFun` because: ^^^^^^^^^^^^^^^^^^^^^^^^^ References: - /react.js:316:25 - 316| (arrayOfTypeCheckers: Array) => + /react.js:320:25 + 320| (arrayOfTypeCheckers: Array) => ^^^^^^^^^^^^^^^^^^^^^^^^^^ [1] proptypes_builtins.js:3:14 3| type NoFun = mixed => empty; ^^^^^ [2] - /react.js:317:5 - 317| ReactPropsChainableTypeChecker; + /react.js:321:5 + 321| ReactPropsChainableTypeChecker; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [3] proptypes_builtins.js:3:23 3| type NoFun = mixed => empty; @@ -2670,14 +2670,14 @@ Cannot cast `React.PropTypes.shape` to `NoFun` because: ^^^^^^^^^^^^^^^^^^^^^ References: - /react.js:319:16 - 319| (shapeTypes: { [key: string]: ReactPropsCheckType }) => + /react.js:323:16 + 323| (shapeTypes: { [key: string]: ReactPropsCheckType }) => ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [1] proptypes_builtins.js:3:14 3| type NoFun = mixed => empty; ^^^^^ [2] - /react.js:320:5 - 320| ReactPropsChainableTypeChecker; + /react.js:324:5 + 324| ReactPropsChainableTypeChecker; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [3] proptypes_builtins.js:3:23 3| type NoFun = mixed => empty; diff --git a/tests/react_children/react_children.exp b/tests/react_children/react_children.exp index 1fee03ca251..3ac2539febf 100644 --- a/tests/react_children/react_children.exp +++ b/tests/react_children/react_children.exp @@ -68,8 +68,8 @@ References: api.js:14:25 14| Children.forEach(a, (x: number) => {}); // Error ^^^^^^ [2] - /react.js:254:38 - 254| declare export type ChildrenArray<+T> = $ReadOnlyArray> | T; + /react.js:257:38 + 257| declare export type ChildrenArray<+T> = $ReadOnlyArray> | T; ^ [3] @@ -90,8 +90,8 @@ References: api.js:16:25 16| Children.forEach(a, (x: string) => {}); // Error ^^^^^^ [2] - /react.js:254:38 - 254| declare export type ChildrenArray<+T> = $ReadOnlyArray> | T; + /react.js:257:38 + 257| declare export type ChildrenArray<+T> = $ReadOnlyArray> | T; ^ [3] api.js:5:25 5| const a: ChildrenArray = [ @@ -107,8 +107,8 @@ Cannot call `s` with `Children.count(...)` bound to `x` because number [1] is in ^^^^^^^^^^^^^^^^^ References: - /react.js:266:42 - 266| count(children: ChildrenArray): number; + /react.js:269:42 + 269| count(children: ChildrenArray): number; ^^^^^^ [1] api.js:29:15 29| function s(x: string) {} diff --git a/tests/react_forward_ref/.flowconfig b/tests/react_forward_ref/.flowconfig new file mode 100644 index 00000000000..de38d19537d --- /dev/null +++ b/tests/react_forward_ref/.flowconfig @@ -0,0 +1,2 @@ +[options] +no_flowlib=false diff --git a/tests/react_forward_ref/react_forward_ref.exp b/tests/react_forward_ref/react_forward_ref.exp new file mode 100644 index 00000000000..8db1af67650 --- /dev/null +++ b/tests/react_forward_ref/react_forward_ref.exp @@ -0,0 +1,50 @@ +Error ------------------------------------------------------------------------------------------------------ test.js:5:1 + +Cannot create `Fr` element because property `foo` is missing in props [1] but exists in object type [2]. + + test.js:5:1 + 5| ; // error: missing `foo` + ^^^^^^ [1] + +References: + test.js:3:19 + 3| function F(props: { foo: string }, ref) { return null; } + ^^^^^^^^^^^^^^^ [2] + + +Error ------------------------------------------------------------------------------------------------------ test.js:6:1 + +Cannot create `Fr` element because number [1] is incompatible with string [2] in property `foo`. + + test.js:6:1 + 6| ; // error: number ~> string + ^^^^^^^^^^^^^^ + +References: + test.js:6:10 + 6| ; // error: number ~> string + ^ [1] + test.js:3:26 + 3| function F(props: { foo: string }, ref) { return null; } + ^^^^^^ [2] + + +Error ---------------------------------------------------------------------------------------------------- test.js:16:18 + +Cannot call `React.forwardRef` with `Z` bound to `render` because number [1] is incompatible with function type [2]. + + test.js:16:18 + 16| React.forwardRef(Z); // error, expected render function + ^ + +References: + test.js:15:9 + 15| var Z = 0; + ^ [1] + /react.js:234:13 + 234| render: (props: Props, ref: React$Ref) => React$Node + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2] + + + +Found 3 errors diff --git a/tests/react_forward_ref/test.js b/tests/react_forward_ref/test.js new file mode 100644 index 00000000000..b5c349be78f --- /dev/null +++ b/tests/react_forward_ref/test.js @@ -0,0 +1,17 @@ +import * as React from "react"; + +function F(props: { foo: string }, ref) { return null; } +const Fr = React.forwardRef(F); +; // error: missing `foo` +; // error: number ~> string +; // ok +Fr.displayName = "Fr"; // ok + +// props subtyping is property-wise covariant +function G(props: { foo: string|number }) { return null; } +const Gr = React.forwardRef(G); +; // ok + +var Z = 0; +React.forwardRef(Z); // error, expected render function + diff --git a/tests/react_imports/react_imports.exp b/tests/react_imports/react_imports.exp index 2e4879cc339..5ad8c440887 100644 --- a/tests/react_imports/react_imports.exp +++ b/tests/react_imports/react_imports.exp @@ -47,8 +47,8 @@ Cannot get `React.Missing` because property `Missing` is missing in module `reac ^^^^^^^^^^^^^ References: - /react.js:293:27 - 293| declare module.exports: $Exports<'react'>; + /react.js:297:27 + 297| declare module.exports: $Exports<'react'>; ^^^^^^^^^^^^^^^^^ [1] @@ -155,8 +155,8 @@ Cannot get `React.Missing` because property `Missing` is missing in module `reac ^^^^^^^^^^^^^ References: - /react.js:293:27 - 293| declare module.exports: $Exports<'react'>; + /react.js:297:27 + 297| declare module.exports: $Exports<'react'>; ^^^^^^^^^^^^^^^^^ [1] @@ -186,25 +186,26 @@ Cannot get `React.Node` because property `Node` is missing in object type [1]. ^^^^^^^^^^ References: - /react.js:271:26 + /react.js:274:26 v- - 271| declare export default {| - 272| +DOM: typeof DOM, - 273| +PropTypes: typeof PropTypes, - 274| +version: typeof version, - 275| +checkPropTypes: typeof checkPropTypes, - 276| +createClass: typeof createClass, - 277| +createContext: typeof createContext, - 278| +createElement: typeof createElement, - 279| +cloneElement: typeof cloneElement, - 280| +createFactory: typeof createFactory, - 281| +createRef: typeof createRef, - 282| +isValidElement: typeof isValidElement, - 283| +Component: typeof Component, - 284| +PureComponent: typeof PureComponent, - 285| +Fragment: typeof Fragment, - 286| +Children: typeof Children, - 287| |}; + 274| declare export default {| + 275| +DOM: typeof DOM, + 276| +PropTypes: typeof PropTypes, + 277| +version: typeof version, + 278| +checkPropTypes: typeof checkPropTypes, + 279| +createClass: typeof createClass, + 280| +createContext: typeof createContext, + 281| +createElement: typeof createElement, + 282| +cloneElement: typeof cloneElement, + 283| +createFactory: typeof createFactory, + 284| +createRef: typeof createRef, + 285| +forwardRef: typeof forwardRef, + 286| +isValidElement: typeof isValidElement, + 287| +Component: typeof Component, + 288| +PureComponent: typeof PureComponent, + 289| +Fragment: typeof Fragment, + 290| +Children: typeof Children, + 291| |}; -^ [1] @@ -217,25 +218,26 @@ Cannot get `React.Node` because property `Node` is missing in object type [1]. ^^^^^^^^^^ References: - /react.js:271:26 + /react.js:274:26 v- - 271| declare export default {| - 272| +DOM: typeof DOM, - 273| +PropTypes: typeof PropTypes, - 274| +version: typeof version, - 275| +checkPropTypes: typeof checkPropTypes, - 276| +createClass: typeof createClass, - 277| +createContext: typeof createContext, - 278| +createElement: typeof createElement, - 279| +cloneElement: typeof cloneElement, - 280| +createFactory: typeof createFactory, - 281| +createRef: typeof createRef, - 282| +isValidElement: typeof isValidElement, - 283| +Component: typeof Component, - 284| +PureComponent: typeof PureComponent, - 285| +Fragment: typeof Fragment, - 286| +Children: typeof Children, - 287| |}; + 274| declare export default {| + 275| +DOM: typeof DOM, + 276| +PropTypes: typeof PropTypes, + 277| +version: typeof version, + 278| +checkPropTypes: typeof checkPropTypes, + 279| +createClass: typeof createClass, + 280| +createContext: typeof createContext, + 281| +createElement: typeof createElement, + 282| +cloneElement: typeof cloneElement, + 283| +createFactory: typeof createFactory, + 284| +createRef: typeof createRef, + 285| +forwardRef: typeof forwardRef, + 286| +isValidElement: typeof isValidElement, + 287| +Component: typeof Component, + 288| +PureComponent: typeof PureComponent, + 289| +Fragment: typeof Fragment, + 290| +Children: typeof Children, + 291| |}; -^ [1] @@ -248,25 +250,26 @@ Cannot get `React.Missing` because property `Missing` is missing in object type ^^^^^^^^^^^^^ References: - /react.js:271:26 + /react.js:274:26 v- - 271| declare export default {| - 272| +DOM: typeof DOM, - 273| +PropTypes: typeof PropTypes, - 274| +version: typeof version, - 275| +checkPropTypes: typeof checkPropTypes, - 276| +createClass: typeof createClass, - 277| +createContext: typeof createContext, - 278| +createElement: typeof createElement, - 279| +cloneElement: typeof cloneElement, - 280| +createFactory: typeof createFactory, - 281| +createRef: typeof createRef, - 282| +isValidElement: typeof isValidElement, - 283| +Component: typeof Component, - 284| +PureComponent: typeof PureComponent, - 285| +Fragment: typeof Fragment, - 286| +Children: typeof Children, - 287| |}; + 274| declare export default {| + 275| +DOM: typeof DOM, + 276| +PropTypes: typeof PropTypes, + 277| +version: typeof version, + 278| +checkPropTypes: typeof checkPropTypes, + 279| +createClass: typeof createClass, + 280| +createContext: typeof createContext, + 281| +createElement: typeof createElement, + 282| +cloneElement: typeof cloneElement, + 283| +createFactory: typeof createFactory, + 284| +createRef: typeof createRef, + 285| +forwardRef: typeof forwardRef, + 286| +isValidElement: typeof isValidElement, + 287| +Component: typeof Component, + 288| +PureComponent: typeof PureComponent, + 289| +Fragment: typeof Fragment, + 290| +Children: typeof Children, + 291| |}; -^ [1] diff --git a/tests/react_jsx/react_jsx.exp b/tests/react_jsx/react_jsx.exp index eac72c8eb48..1d7b0997c00 100644 --- a/tests/react_jsx/react_jsx.exp +++ b/tests/react_jsx/react_jsx.exp @@ -93,8 +93,8 @@ References: test.js:105:12 105| string1={null} ^^^^ [1] - /react.js:328:36 - 328| string: React$PropType$Primitive; + /react.js:332:36 + 332| string: React$PropType$Primitive; ^^^^^^ [2] test.js:106:12 106| string2={null} @@ -102,8 +102,8 @@ References: test.js:107:13 107| boolean1={null} ^^^^ [4] - /react.js:324:34 - 324| bool: React$PropType$Primitive; + /react.js:328:34 + 328| bool: React$PropType$Primitive; ^^^^^^^ [5] test.js:108:13 108| boolean2={null} @@ -111,8 +111,8 @@ References: test.js:109:11 109| number={null} ^^^^ [7] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [8] @@ -161,8 +161,8 @@ References: test.js:135:54 135| {...{string1: 'foo', string2: 'bar', number: (any: ?number)}} ^^^^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -1654,8 +1654,8 @@ References: /core.js:13:24 13| declare var undefined: void; ^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -1675,8 +1675,8 @@ References: test.js:788:7 788| foo="nope" ^^^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] @@ -1696,8 +1696,8 @@ References: test.js:793:7 793| bar="nope" ^^^^^^ [1] - /react.js:326:36 - 326| number: React$PropType$Primitive; + /react.js:330:36 + 330| number: React$PropType$Primitive; ^^^^^^ [2] diff --git a/tests/type-at-pos/type-at-pos.exp b/tests/type-at-pos/type-at-pos.exp index 4370bfeffaa..554adf16867 100644 --- a/tests/type-at-pos/type-at-pos.exp +++ b/tests/type-at-pos/type-at-pos.exp @@ -2693,7 +2693,7 @@ predicates.js - if (Array.isArray(y.FOO)): { "end":23 } react_component.js:3:9 = { - "type":"{|+Children: {+count: (children: ChildrenArray) => number, +forEach: (children: ChildrenArray, fn: (child: T, index: number) => mixed, thisArg?: mixed) => void, +map: (children: ChildrenArray, fn: (child: $NonMaybeType, index: number) => U, thisArg?: mixed) => Array<$NonMaybeType>, +only: (children: ChildrenArray) => $NonMaybeType, +toArray: (children: ChildrenArray) => Array<$NonMaybeType>}, +ChildrenArray: type ChildrenArray<+T> = $ReadOnlyArray> | T, +Component: class React$Component, +ComponentType: type ComponentType

= React$ComponentType

, +Context: type Context = React$Context, +DOM: any, +Element: type Element<+C> = React$Element, +ElementConfig: type ElementConfig = React$ElementConfig, +ElementProps: type ElementProps = React$ElementProps, +ElementRef: type ElementRef = React$ElementRef, +ElementType: type ElementType = React$ElementType, +Fragment: ({children: ?React$Node}) => React$Node, +Key: type Key = React$Key, +Node: type Node = React$Node, +Portal: type Portal = React$Portal, +PropTypes: ReactPropTypes, +PureComponent: class React$PureComponent, +Ref: type Ref = React$Ref, +StatelessFunctionalComponent: type StatelessFunctionalComponent

= React$StatelessFunctionalComponent

, +checkPropTypes: (propTypes: $Subtype<{[_: $Keys]: ReactPropsCheckType}>, values: V, location: string, componentName: string, getStack: ?(() => ?string)) => void, +cloneElement: React$CloneElement, +createClass: React$CreateClass, +createContext: (defaultValue: T) => React$Context, +createElement: React$CreateElement, +createFactory: (type: ElementType) => React$ElementFactory, +createRef: () => {current: (null | React$ElementRef)}, +default: {|+Children: {+count: (children: ChildrenArray) => number, +forEach: (children: ChildrenArray, fn: (child: T, index: number) => mixed, thisArg?: mixed) => void, +map: (children: ChildrenArray, fn: (child: $NonMaybeType, index: number) => U, thisArg?: mixed) => Array<$NonMaybeType>, +only: (children: ChildrenArray) => $NonMaybeType, +toArray: (children: ChildrenArray) => Array<$NonMaybeType>}, +Component: class React$Component, +DOM: any, +Fragment: ({children: ?React$Node}) => React$Node, +PropTypes: ReactPropTypes, +PureComponent: class React$PureComponent, +checkPropTypes: (propTypes: $Subtype<{[_: $Keys]: ReactPropsCheckType}>, values: V, location: string, componentName: string, getStack: ?(() => ?string)) => void, +cloneElement: React$CloneElement, +createClass: React$CreateClass, +createContext: (defaultValue: T) => React$Context, +createElement: React$CreateElement, +createFactory: (type: ElementType) => React$ElementFactory, +createRef: () => {current: (null | React$ElementRef)}, +isValidElement: (element: any) => boolean, +version: string|}, +isValidElement: (element: any) => boolean, +version: string|}", + "type":"{|+Children: {+count: (children: ChildrenArray) => number, +forEach: (children: ChildrenArray, fn: (child: T, index: number) => mixed, thisArg?: mixed) => void, +map: (children: ChildrenArray, fn: (child: $NonMaybeType, index: number) => U, thisArg?: mixed) => Array<$NonMaybeType>, +only: (children: ChildrenArray) => $NonMaybeType, +toArray: (children: ChildrenArray) => Array<$NonMaybeType>}, +ChildrenArray: type ChildrenArray<+T> = $ReadOnlyArray> | T, +Component: class React$Component, +ComponentType: type ComponentType

= React$ComponentType

, +Context: type Context = React$Context, +DOM: any, +Element: type Element<+C> = React$Element, +ElementConfig: type ElementConfig = React$ElementConfig, +ElementProps: type ElementProps = React$ElementProps, +ElementRef: type ElementRef = React$ElementRef, +ElementType: type ElementType = React$ElementType, +Fragment: ({children: ?React$Node}) => React$Node, +Key: type Key = React$Key, +Node: type Node = React$Node, +Portal: type Portal = React$Portal, +PropTypes: ReactPropTypes, +PureComponent: class React$PureComponent, +Ref: type Ref = React$Ref, +StatelessFunctionalComponent: type StatelessFunctionalComponent

= React$StatelessFunctionalComponent

, +checkPropTypes: (propTypes: $Subtype<{[_: $Keys]: ReactPropsCheckType}>, values: V, location: string, componentName: string, getStack: ?(() => ?string)) => void, +cloneElement: React$CloneElement, +createClass: React$CreateClass, +createContext: (defaultValue: T) => React$Context, +createElement: React$CreateElement, +createFactory: (type: ElementType) => React$ElementFactory, +createRef: () => {current: (null | React$ElementRef)}, +default: {|+Children: {+count: (children: ChildrenArray) => number, +forEach: (children: ChildrenArray, fn: (child: T, index: number) => mixed, thisArg?: mixed) => void, +map: (children: ChildrenArray, fn: (child: $NonMaybeType, index: number) => U, thisArg?: mixed) => Array<$NonMaybeType>, +only: (children: ChildrenArray) => $NonMaybeType, +toArray: (children: ChildrenArray) => Array<$NonMaybeType>}, +Component: class React$Component, +DOM: any, +Fragment: ({children: ?React$Node}) => React$Node, +PropTypes: ReactPropTypes, +PureComponent: class React$PureComponent, +checkPropTypes: (propTypes: $Subtype<{[_: $Keys]: ReactPropsCheckType}>, values: V, location: string, componentName: string, getStack: ?(() => ?string)) => void, +cloneElement: React$CloneElement, +createClass: React$CreateClass, +createContext: (defaultValue: T) => React$Context, +createElement: React$CreateElement, +createFactory: (type: ElementType) => React$ElementFactory, +createRef: () => {current: (null | React$ElementRef)}, +forwardRef: (render: (props: Props, ref: React$Ref) => React$Node) => React$ComponentType, +isValidElement: (element: any) => boolean, +version: string|}, +forwardRef: (render: (props: Props, ref: React$Ref) => React$Node) => React$ComponentType, +isValidElement: (element: any) => boolean, +version: string|}", "reasons":[], "loc":{ "source":"react_component.js", @@ -2806,7 +2806,7 @@ react_component.js:32:13 = { "kind":"Generic", "typeArgs":[{"kind":"Num"}], "type":{ - "provenance":{"kind":"Library","loc":"[LIB] react.js:240:42-60"}, + "provenance":{"kind":"Library","loc":"[LIB] react.js:243:42-60"}, "name":"ComponentType" }, "structural":false @@ -2829,7 +2829,7 @@ react_component.js:32:29 = { "expanded_type":{ "kind":"TypeAlias", "name":{ - "provenance":{"kind":"Library","loc":"[LIB] react.js:240:42-60"}, + "provenance":{"kind":"Library","loc":"[LIB] react.js:243:42-60"}, "name":"ComponentType" }, "typeParams":[{"name":"P","bound":null,"polarity":"Neutral"}],