From fb669962a0300d3a00f1f1a2ecc104b6f9c51267 Mon Sep 17 00:00:00 2001 From: William Chargin Date: Mon, 22 Jun 2020 10:42:36 -0700 Subject: [PATCH] combo: make `JsonObject` arrays/objects covariant (#1885) Summary: This is more general: a mutable type is a subtype of its corresponding read-only type. Using the covariant form lets structures like `string[]` be subtypes of `JsonObject`, as `T[]` is not (in general) a subtype of `(T | U)[]` but is a subtype of `$ReadOnlyArray`. Test Plan: Demonstration type-level tests added. wchargin-branch: jsonobject-readonly --- src/util/combo.js | 4 ++-- src/util/combo.test.js | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/util/combo.js b/src/util/combo.js index 4bb73e6..00b5ffe 100644 --- a/src/util/combo.js +++ b/src/util/combo.js @@ -8,8 +8,8 @@ export type JsonObject = | number | boolean | null - | JsonObject[] - | {[string]: JsonObject}; + | $ReadOnlyArray + | {+[string]: JsonObject}; export type ParseResult<+T> = | {|+ok: true, +value: T|} diff --git a/src/util/combo.test.js b/src/util/combo.test.js index 1852c20..fec3418 100644 --- a/src/util/combo.test.js +++ b/src/util/combo.test.js @@ -3,6 +3,14 @@ import * as C from "./combo"; describe("src/util/combo", () => { + describe("type JsonObject", () => { + it("includes compound structures of strict subtypes", () => { + // (requires covariance in the array/object clauses) + (x: string[]): C.JsonObject => x; + (x: {[string]: number}): C.JsonObject => x; + }); + }); + describe("primitives", () => { describe("string", () => { it("accepts strings", () => {