Permalink
Browse files

nuke RecordT

Summary: $Record types were experimental, and kind of rotting as a third object-like
def type besides ObjT and InstanceT.

It turns out that its functionality can be covered by $Enum and dict types.
So there is no use for it.

In fact, using $Enum and dict types, you can get better $Record types because
you can also specify the value type!

Also simplified type of propTypes to Object.
With this diff we could replace it with $Subtype<{[key: $Enum<P>]: any]}>.
But in a follow-up diff, we're going to make propTypes allow spreads etc.
which may interfere with such a type. Moving forward ES6 React doesn't have a
good story around propTypes anyway, and for legacy React that annotation is
not even touched, so Object should really be enough.

Reviewed By: @mroch

Differential Revision: D2132989
  • Loading branch information...
avikchaudhuri authored and facebook-github-bot-7 committed Jun 6, 2015
1 parent f4178d5 commit 6d4447b0300494f8a235f4d0907bee438705ba19
View
@@ -41,7 +41,7 @@ declare class ReactComponent<D, P, S> {
componentWillUnmount(): void;
isMounted(): bool;
static propTypes: $Supertype<$Record<P>>;
static propTypes: $Subtype<{[_: $Enum<P>]: any}>; //object whose keys are in P
static contextTypes: any;
static childContextTypes: any;
static displayName: string;
@@ -148,8 +148,6 @@ module Type = struct
(* collects the keys of an object *)
| EnumT of reason * t
(* constrains the keys of an object *)
| RecordT of reason * t
(* type aliases *)
| TypeT of reason * t
@@ -711,7 +709,6 @@ let string_of_ctor = function
| ShapeT _ -> "ShapeT"
| DiffT _ -> "DiffT"
| EnumT _ -> "EnumT"
| RecordT _ -> "RecordT"
| KeyT _ -> "KeyT"
| HasT _ -> "HasT"
| ElemT _ -> "ElemT"
@@ -841,7 +838,6 @@ let rec reason_of_t = function
-> reason_of_t t
| EnumT (reason, _)
| RecordT (reason, _)
->
reason
@@ -985,7 +981,6 @@ let rec mod_reason_of_t f = function
| DiffT (t1, t2) -> DiffT (mod_reason_of_t f t1, t2)
| EnumT (reason, t) -> EnumT (f reason, t)
| RecordT (reason, t) -> RecordT (f reason, t)
| KeyT (reason, t) -> KeyT (f reason, t)
| HasT (reason, t) -> HasT (f reason, t)
@@ -1205,9 +1200,6 @@ let rec type_printer override fallback enclosure cx t =
| AnyFunT _ ->
"Function"
| RecordT (_, t) ->
spf "$Record<%s>" (pp EnclosureNone cx t)
| t ->
fallback t
@@ -1356,8 +1348,7 @@ let rec _json_of_t stack cx t = Json.(
"type2", _json_of_t stack cx t2
]
| EnumT (_, t)
| RecordT (_, t) -> [
| EnumT (_, t) -> [
"type", _json_of_t stack cx t
]
@@ -1885,7 +1876,6 @@ let rec is_printed_type_parsable_impl weak cx enclosure = function
| TypeT (_, t)
| LowerBoundT t
| UpperBoundT t
| RecordT (_, t)
| ClassT t
when weak
->
@@ -66,7 +66,6 @@ module Type :
| DiffT of t * t
| EnumT of reason * t
| RecordT of reason * t
| TypeT of reason * t
| BecomeT of reason * t
View
@@ -689,12 +689,6 @@ and ground_type_impl cx ids t = match t with
| DiffT (t1, t2) ->
DiffT (ground_type_impl cx ids t1, ground_type_impl cx ids t2)
| RecordT (_, t) ->
RecordT (
reason_of_string "record",
ground_type_impl cx ids t
)
| _ -> assert false (** TODO **)
and lookup_type_ cx ids id =
@@ -796,9 +790,6 @@ let rec normalize_type cx t =
| DiffT (t1, t2) ->
DiffT (normalize_type cx t1, normalize_type cx t2)
| RecordT (r, t) ->
RecordT (r, normalize_type cx t)
(* TODO: Normalize all types? *)
| t -> t
@@ -968,9 +959,6 @@ let rec printify_type cx t =
| DiffT (t1, t2) ->
DiffT (printify_type cx t1, printify_type cx t2)
| RecordT (r, t) ->
RecordT (r, printify_type cx t)
| t -> t
let printified_type cx t =
@@ -1105,9 +1093,6 @@ let rec assert_ground ?(infer=false) cx ids = function
| EnumT(reason,t) ->
assert_ground cx ids t
| RecordT(reason,t) ->
assert_ground cx ids t
| CJSExportDefaultT (reason,t) ->
assert_ground ~infer:true cx ids t
@@ -2577,15 +2562,6 @@ let rec __flow cx (l, u) trace =
| (EnumT (reason1, o1), _) ->
rec_flow cx trace (o1, KeyT (reason1, u))
| (_, RecordT (reason2, o2)) ->
rec_flow cx trace (o2, KeyT(reason2, EnumT(reason2, l)))
| (RecordT (reason, o2),
(HasT(_,x) |
LookupT(_,_,x,_) | GetT(_,x,_) | SetT(_,x,_) | MethodT(_,x,_,_,_,_)))
->
rec_flow cx trace (o2, HasT(reason_of_t u,x))
| (ObjT (reason_o, { props_tmap = mapr; _ }), HasT(reason_op, x)) ->
if has_prop cx mapr x then ()
else
@@ -2609,9 +2585,6 @@ let rec __flow cx (l, u) trace =
(reason_op, reason_o)
)
| (RecordT (reason, o2), KeyT(reason_, key)) ->
rec_flow cx trace (o2, KeyT(reason_, key))
| (ObjT (reason, { props_tmap = mapr; _ }), KeyT(_,key)) ->
iter_props cx mapr (fun x tv ->
let t = StrT (reason, Some x) in
@@ -2627,11 +2600,6 @@ let rec __flow cx (l, u) trace =
rec_flow cx trace (t, key)
)
| (RecordT (reason, o2), (ObjT _ | InstanceT _)) ->
let tvar = mk_tvar cx reason in
rec_flow cx trace (u, KeyT(reason, tvar));
rec_flow cx trace (tvar, EnumT(reason, o2))
(*********************)
(* functions statics *)
(*********************)
@@ -2895,7 +2863,7 @@ and numeric = function
| _ -> false
and object_like = function
| ObjT _ | InstanceT _ | RecordT _ -> true
| ObjT _ | InstanceT _ -> true
| t -> function_like t
and object_like_op = function
@@ -3116,9 +3084,6 @@ and subst cx ?(force=true) (map: Type.t SMap.t) t =
| EnumT(reason, t) ->
EnumT(reason, subst cx ~force map t)
| RecordT(reason, t) ->
RecordT(reason, subst cx ~force map t)
| ObjAssignT(reason, t1, t2, xs, resolve) ->
ObjAssignT(reason, subst cx ~force map t1, subst cx ~force map t2, xs, resolve)
@@ -625,13 +625,6 @@ let rec convert cx map = Ast.Type.(function
EnumT (mk_reason "enum type" loc, t)
)
(* $Record<T> is the type of objects whose keys are those of T *)
| "$Record" ->
check_type_param_arity cx loc typeParameters 1 (fun () ->
let t = convert cx map (List.hd typeParameters) in
RecordT (mk_reason "record type" loc, t)
)
(* $Exports<'M'> is the type of the exports of module 'M' *)
(** TODO: use `import typeof` instead when that lands **)
| "$Exports" ->
View
No changes.
View
@@ -0,0 +1,18 @@
test.js:4:8,9: string
This type is incompatible with
test.js:2:23,28: number
test.js:7:1,6: property name "qux" is a string
This type is incompatible with
test.js:1:13,25: union type
test.js:13:1,6: string literal qux
Property not found in
test.js:9:10,29: object type
test.js:19:6,34: string literal qux
Property not found in
test.js:18:19,44: object type
Found 4 errors
View
@@ -0,0 +1,20 @@
type Key1 = 'foo' | 'bar'; // make an enum type with known key set
var o1: {[key: Key1]: number} = {
foo: 0,
bar: "", // error: string ~/~ number
};
o1.foo; // OK
o1.qux; // error: qux not found
type R = {foo: any, bar: any};
type Key2 = $Enum<R>; // another way to make an enum type, with unknown key set
var o2: {[key: Key2]: number} = { foo: 0 }; // OK to leave out bar
o2.bar; // OK to access bar
o2.qux; // error: qux not found
class C<X> {
x: $Subtype<{[key: $Enum<X>]: any}>; // object with larger key set than X's
}
class D extends C<{foo: number, bar: string}> {
x: { foo: number, qux: boolean }; // error: qux not found
}

0 comments on commit 6d4447b

Please sign in to comment.