Skip to content

Commit 93be5be

Browse files
SamChou19815facebook-github-bot
authored andcommitted
[flow] Relax component type instance subtyping rule
Summary: This diff relaxes the component type instance subtyping rule to further align with ref-as-prop model. Specifically, `React.ComponentType<{}> ~> component()` will be allowed, and ideally `component() ~> React.ComponentType<{}>` should be banned (but not yet for compatibility reasons for now, since we need to accept things like `fn component without ref prop ~> React.ComponentType<{}>` which is allowed forever) for the reason described in the comments. Changelog: [fixed] We now allow something of type `React.ComponentType<{}>` to be a subtype of `component()` Reviewed By: jbrown215 Differential Revision: D69542576 fbshipit-source-id: d6265f683b130df15c2d05214cf15fb8395b6c61
1 parent fe1f33b commit 93be5be

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

src/typing/subtyping_kit.ml

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -592,15 +592,26 @@ module Make (Flow : INPUT) : OUTPUT = struct
592592
->
593593
(* ref prop is contravariantly typed. We need to flip the flow. *)
594594
rec_flow_t cx trace ~use_op (r, l)
595-
(* In the following two cases, we can still directly flow the type to each other *)
596-
(* component() (equivalent to component(ref?: React.RefSetter<void>))
597-
* ~> React.ComponentType<{}> (equivalent to component(ref?: React.RefSetter<mixed>)) *)
598-
| (ComponentInstanceOmitted r1, ComponentInstanceTopType r2) ->
599-
rec_flow_t cx trace ~use_op (VoidT.make r1, MixedT.why r2)
600-
(* React.ComponentType<{}> (equivalent to component(ref?: React.RefSetter<mixed>))
601-
* ~> component() (equivalent to component(ref?: React.RefSetter<void>)) *)
602-
| (ComponentInstanceTopType r1, ComponentInstanceOmitted r2) ->
603-
rec_flow_t cx trace ~use_op (MixedT.why r1, VoidT.make r2)
595+
(* component() (treated as component(ref?: React.RefSetter<void>))
596+
* ~> React.ComponentType<{}> (equivalent to component(ref?: React.RefSetter<mixed>))
597+
*
598+
* This is allowed since void ~> mixed, but only temporarily, because `component()` being treated
599+
* as component(ref?: React.RefSetter<void>) is a result of intermediate ref-as-prop migration.
600+
* In the future, it should be banned, in the same way that
601+
* `{+ref?: React.RefSetter<mixed>} ~> {}` is banned. *)
602+
| (ComponentInstanceOmitted _, ComponentInstanceTopType _) -> ()
603+
(* React.ComponentType<{}> (equivalent to component(ref?: React.RefSetter<mixed>)) ~> component()
604+
*
605+
* If `component()` is treated as component(ref?: React.RefSetter<void>), it will fail due to
606+
* `mixed ~> void`. However, this treatement is temporary while we are moving to full ref-as-prop
607+
* model, in the ref as prop model, the subtyping behavior should be
608+
*
609+
* React.ComponentType<{}> (equivalent to component(ref?: React.RefSetter<mixed>)) ~> component()
610+
* -> component(ref?: React.RefSetter<mixed>) ~> component()
611+
* -> {} ~> {+ref?: React.RefSetter<mixed>}
612+
* -> OK!
613+
* *)
614+
| (ComponentInstanceTopType _, ComponentInstanceOmitted _) -> ()
604615
(* The most tricky cases: LHS and RHS have different kinds of instance information,
605616
* and one side is ComponentInstanceAvailableAsRefSetterProp. We need to wrap the side
606617
* that's not ComponentInstanceAvailableAsRefSetterProp with React.RefSetter *)

0 commit comments

Comments
 (0)