MapUtil: provide exact output from `toObject` (#993)
Summary: The `MapUtil` map–object conversion functions used inexact objects for both input and output. They are in fact stronger than that: they can accept arbitrary inexact objects and return arbitrary exact outputs. (Recall that exact objects are subtypes of their inexact counterparts, so this is the maximally permissive combination.) Test Plan: Unit tests added. The “can return an exact object” test fails Flow before this change. The other tests would have passed already. wchargin-branch: maputil-exact-output
This commit is contained in:
parent
252d8d5c99
commit
beccac822f
|
@ -7,8 +7,8 @@
|
|||
*/
|
||||
export function toObject<K: string, V, InK: K, InV: V>(
|
||||
map: Map<InK, InV>
|
||||
): {[K]: V} {
|
||||
const result = {};
|
||||
): {|[K]: V|} {
|
||||
const result: {|[K]: V|} = ({}: any);
|
||||
for (const [k, v] of map.entries()) {
|
||||
result[k] = v;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,14 @@ describe("util/map", () => {
|
|||
const output: {[Fruit]: string} = MapUtil.toObject(input);
|
||||
expect(output).toEqual({APPLE: "good", ORANGE: "also good"});
|
||||
});
|
||||
it("can return an exact object", () => {
|
||||
const _: {|[string]: number|} = MapUtil.toObject(new Map().set("a", 1));
|
||||
});
|
||||
it("can return an inexact object", () => {
|
||||
// This should be free: exact objects are subtypes of their
|
||||
// inexact counterparts.
|
||||
const _: {[string]: number} = MapUtil.toObject(new Map().set("a", 1));
|
||||
});
|
||||
it("statically rejects a map with keys not a subtype of string", () => {
|
||||
const input: Map<number, string> = new Map()
|
||||
.set(12, "not okay")
|
||||
|
@ -53,6 +61,16 @@ describe("util/map", () => {
|
|||
new Map().set("APPLE", "good").set("ORANGE", "also good")
|
||||
);
|
||||
});
|
||||
it("can accept an inexact object", () => {
|
||||
const o: {[string]: number} = {a: 1};
|
||||
const _: Map<string, number> = MapUtil.fromObject(o);
|
||||
});
|
||||
it("can accept an exact object", () => {
|
||||
// This should be free: exact objects are subtypes of their
|
||||
// inexact counterparts.
|
||||
const o: {|[string]: number|} = ({a: 1}: any);
|
||||
const _: Map<string, number> = MapUtil.fromObject(o);
|
||||
});
|
||||
it("statically rejects a map with keys not a subtype of string", () => {
|
||||
const input: {[number]: string} = {};
|
||||
input[12] = "not okay";
|
||||
|
|
Loading…
Reference in New Issue