decoders 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/json.js.flow CHANGED
@@ -15,12 +15,12 @@ export type JSONObject = { [string]: JSONValue };
15
15
  export type JSONArray = Array<JSONValue>;
16
16
 
17
17
  /**
18
- * Like `json`, but will only decode when the JSON value is an object.
18
+ * Accepts objects that contain only valid JSON values.
19
19
  */
20
20
  export const jsonObject: Decoder<JSONObject> = lazy(() => dict(json));
21
21
 
22
22
  /**
23
- * Like `json`, but will only decode when the JSON value is an array.
23
+ * Accepts arrays that contain only valid JSON values.
24
24
  */
25
25
  export const jsonArray: Decoder<JSONArray> = lazy(() => array(json));
26
26
 
package/lib/json.mjs CHANGED
@@ -1,40 +1,18 @@
1
- import { array } from './arrays.mjs';
2
- import { boolean as _boolean } from './booleans.mjs';
3
- import { dict } from './objects.mjs';
4
- import { either } from './unions.mjs';
5
- import { lazy } from './utilities.mjs';
6
- import { null_ } from './basics.mjs';
7
- import { number } from './numbers.mjs';
8
- import { string } from './strings.mjs';
1
+ import { array } from './arrays.mjs'
2
+ import { boolean as _boolean } from './booleans.mjs'
3
+ import { dict } from './objects.mjs'
4
+ import { either } from './unions.mjs'
5
+ import { lazy } from './utilities.mjs'
6
+ import { null_ } from './basics.mjs'
7
+ import { number } from './numbers.mjs'
8
+ import { string } from './strings.mjs'
9
9
 
10
- /**
11
- * Like `json`, but will only decode when the JSON value is an object.
12
- */
13
10
  export var jsonObject = lazy(function () {
14
- return dict(json);
15
- });
16
- /**
17
- * Like `json`, but will only decode when the JSON value is an array.
18
- */
11
+ return dict(json)
12
+ })
19
13
 
20
14
  export var jsonArray = lazy(function () {
21
- return array(json);
22
- });
23
- /**
24
- * Accepts any value that's a valid JSON value.
25
- *
26
- * In other words: any value returned by `JSON.parse()` should decode without
27
- * failure.
28
- *
29
- * ```typescript
30
- * type JSONValue =
31
- * | null
32
- * | string
33
- * | number
34
- * | boolean
35
- * | { [string]: JSONValue }
36
- * | JSONValue[]
37
- * ```
38
- */
15
+ return array(json)
16
+ })
39
17
 
40
- export var json = either(null_, string, number, _boolean, jsonObject, jsonArray).describe('Must be valid JSON value');
18
+ export var json = either(null_, string, number, _boolean, jsonObject, jsonArray).describe('Must be valid JSON value')
package/lib/numbers.js CHANGED
@@ -1,51 +1,31 @@
1
- "use strict";
1
+ 'use strict'
2
2
 
3
- exports.__esModule = true;
4
- exports.positiveNumber = exports.positiveInteger = exports.number = exports.integer = exports.anyNumber = void 0;
3
+ exports.__esModule = true
4
+ exports.positiveNumber = exports.positiveInteger = exports.number = exports.integer = exports.anyNumber = void 0
5
5
 
6
- var _Decoder = require("../Decoder");
6
+ var _Decoder = require('../Decoder')
7
7
 
8
- /**
9
- * Accepts any valid ``number`` value.
10
- *
11
- * This also accepts special values like `NaN` and `Infinity`. Unless you
12
- * want to deliberately accept those, you'll likely want to use the
13
- * `number` decoder instead.
14
- */
15
8
  var anyNumber = (0, _Decoder.define)(function (blob, ok, err) {
16
- return typeof blob === 'number' ? ok(blob) : err('Must be number');
17
- });
18
- /**
19
- * Accepts finite numbers (can be integer or float values). Values `NaN`,
20
- * or positive and negative `Infinity` will get rejected.
21
- */
9
+ return typeof blob === 'number' ? ok(blob) : err('Must be number')
10
+ })
22
11
 
23
- exports.anyNumber = anyNumber;
12
+ exports.anyNumber = anyNumber
24
13
  var number = anyNumber.refine(function (n) {
25
- return Number.isFinite(n);
26
- }, 'Number must be finite');
27
- /**
28
- * Accepts only finite whole numbers.
29
- */
14
+ return Number.isFinite(n)
15
+ }, 'Number must be finite')
30
16
 
31
- exports.number = number;
17
+ exports.number = number
32
18
  var integer = number.refine(function (n) {
33
- return Number.isInteger(n);
34
- }, 'Number must be an integer');
35
- /**
36
- * Accepts only positive finite numbers.
37
- */
19
+ return Number.isInteger(n)
20
+ }, 'Number must be an integer')
38
21
 
39
- exports.integer = integer;
22
+ exports.integer = integer
40
23
  var positiveNumber = number.refine(function (n) {
41
- return n >= 0;
42
- }, 'Number must be positive');
43
- /**
44
- * Accepts only positive finite whole numbers.
45
- */
24
+ return n >= 0
25
+ }, 'Number must be positive')
46
26
 
47
- exports.positiveNumber = positiveNumber;
27
+ exports.positiveNumber = positiveNumber
48
28
  var positiveInteger = integer.refine(function (n) {
49
- return n >= 0;
50
- }, 'Number must be positive');
51
- exports.positiveInteger = positiveInteger;
29
+ return n >= 0
30
+ }, 'Number must be positive')
31
+ exports.positiveInteger = positiveInteger
package/lib/numbers.mjs CHANGED
@@ -1,41 +1,21 @@
1
- import { define } from '../Decoder.mjs';
1
+ import { define } from '../Decoder.mjs'
2
2
 
3
- /**
4
- * Accepts any valid ``number`` value.
5
- *
6
- * This also accepts special values like `NaN` and `Infinity`. Unless you
7
- * want to deliberately accept those, you'll likely want to use the
8
- * `number` decoder instead.
9
- */
10
3
  export var anyNumber = define(function (blob, ok, err) {
11
- return typeof blob === 'number' ? ok(blob) : err('Must be number');
12
- });
13
- /**
14
- * Accepts finite numbers (can be integer or float values). Values `NaN`,
15
- * or positive and negative `Infinity` will get rejected.
16
- */
4
+ return typeof blob === 'number' ? ok(blob) : err('Must be number')
5
+ })
17
6
 
18
7
  export var number = anyNumber.refine(function (n) {
19
- return Number.isFinite(n);
20
- }, 'Number must be finite');
21
- /**
22
- * Accepts only finite whole numbers.
23
- */
8
+ return Number.isFinite(n)
9
+ }, 'Number must be finite')
24
10
 
25
11
  export var integer = number.refine(function (n) {
26
- return Number.isInteger(n);
27
- }, 'Number must be an integer');
28
- /**
29
- * Accepts only positive finite numbers.
30
- */
12
+ return Number.isInteger(n)
13
+ }, 'Number must be an integer')
31
14
 
32
15
  export var positiveNumber = number.refine(function (n) {
33
- return n >= 0;
34
- }, 'Number must be positive');
35
- /**
36
- * Accepts only positive finite whole numbers.
37
- */
16
+ return n >= 0
17
+ }, 'Number must be positive')
38
18
 
39
19
  export var positiveInteger = integer.refine(function (n) {
40
- return n >= 0;
41
- }, 'Number must be positive');
20
+ return n >= 0
21
+ }, 'Number must be positive')
package/lib/objects.d.ts CHANGED
@@ -11,14 +11,14 @@ export type ObjectDecoderType<T> = AllowImplicit<{
11
11
  * Accepts any "plain old JavaScript object", but doesn't validate its keys or
12
12
  * values further.
13
13
  */
14
- export const pojo: Decoder<{ [key: string]: unknown }>;
14
+ export const pojo: Decoder<Record<string, unknown>>;
15
15
 
16
16
  /**
17
17
  * Accepts objects with fields matching the given decoders. Extra fields that
18
18
  * exist on the input object are ignored and will not be returned.
19
19
  */
20
20
  export function object(decodersByKey: Record<any, never>): Decoder<Record<string, never>>;
21
- export function object<O extends { [key: string]: Decoder<any> }>(
21
+ export function object<O extends Record<string, Decoder<any>>>(
22
22
  decodersByKey: O,
23
23
  ): Decoder<{ [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] }>;
24
24
  // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,7 +34,7 @@ export function object<O extends { [key: string]: Decoder<any> }>(
34
34
  * not specified explicitly.
35
35
  */
36
36
  export function exact(decodersByKey: Record<any, never>): Decoder<Record<string, never>>;
37
- export function exact<O extends { [key: string]: Decoder<any> }>(
37
+ export function exact<O extends Record<string, Decoder<any>>>(
38
38
  decodersByKey: O,
39
39
  ): Decoder<{ [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] }>;
40
40
  // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -46,18 +46,19 @@ export function exact<O extends { [key: string]: Decoder<any> }>(
46
46
  */
47
47
  export function inexact(
48
48
  decodersByKey: Record<any, never>,
49
- ): Decoder<{ [extra: string]: unknown }>;
50
- export function inexact<O extends { [key: string]: Decoder<any> }>(
49
+ ): Decoder<Record<string, unknown>>;
50
+ export function inexact<O extends Record<string, Decoder<any>>>(
51
51
  decodersByKey: O,
52
52
  ): Decoder<
53
- { [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] } & {
54
- [extra: string]: unknown;
55
- }
53
+ { [K in keyof ObjectDecoderType<O>]: ObjectDecoderType<O>[K] } & Record<
54
+ string,
55
+ unknown
56
+ >
56
57
  >;
57
58
 
58
59
  /**
59
60
  * Accepts objects where all values match the given decoder, and returns the
60
- * result as a `{ [string]: T }`.
61
+ * result as a `Record<string, T>`.
61
62
  *
62
63
  * The main difference between `object()` and `dict()` is that you'd typically
63
64
  * use `object()` if this is a record-like object, where all field names are
@@ -65,7 +66,7 @@ export function inexact<O extends { [key: string]: Decoder<any> }>(
65
66
  * typically dynamic and the values homogeneous, like in a dictionary,
66
67
  * a lookup table, or a cache.
67
68
  */
68
- export function dict<T>(decoder: Decoder<T>): Decoder<{ [key: string]: T }>;
69
+ export function dict<T>(decoder: Decoder<T>): Decoder<Record<string, T>>;
69
70
 
70
71
  /**
71
72
  * Similar to `dict()`, but returns the result as a `Map<string, T>` (an [ES6
package/lib/objects.js CHANGED
@@ -1,240 +1,161 @@
1
- "use strict";
1
+ 'use strict'
2
2
 
3
- exports.__esModule = true;
4
- exports.dict = dict;
5
- exports.exact = exact;
6
- exports.inexact = inexact;
7
- exports.mapping = mapping;
8
- exports.object = object;
9
- exports.pojo = void 0;
3
+ exports.__esModule = true
4
+ exports.dict = dict
5
+ exports.exact = exact
6
+ exports.inexact = inexact
7
+ exports.mapping = mapping
8
+ exports.object = object
9
+ exports.pojo = void 0
10
10
 
11
- var _annotate = require("../annotate");
11
+ var _annotate = require('../annotate')
12
12
 
13
- var _Decoder = require("../Decoder");
14
-
15
- function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
16
-
17
- function subtract(xs, ys) {
18
- var result = new Set();
19
- xs.forEach(function (x) {
20
- if (!ys.has(x)) {
21
- result.add(x);
22
- }
23
- });
24
- return result;
25
- }
26
- /**
27
- * Accepts any "plain old JavaScript object", but doesn't validate its keys or
28
- * values further.
29
- */
13
+ var _Decoder = require('../Decoder')
30
14
 
15
+ var _utils = require('../_utils')
31
16
 
32
17
  var pojo = (0, _Decoder.define)(function (blob, ok, err) {
33
- return blob !== null && blob !== undefined && typeof blob === 'object' && // This still seems to be the only reliable way to determine whether
34
- // something is a pojo... ¯\_(ツ)_/¯
35
- // $FlowFixMe[method-unbinding]
36
- Object.prototype.toString.call(blob) === '[object Object]' ? ok( // NOTE:
37
- // Since Flow 0.98, typeof o === 'object' refines to
38
- // {| +[string]: mixed |}
39
- // instead of
40
- // {| [string]: mixed |}
41
- //
42
- // For rationale, see https://github.com/facebook/flow/issues/7685.
43
- // In this case, we don't want to output a read-only version of
44
- // the object because it's up to the user of decoders to
45
- // determine what they want to do with the decoded output. If they
46
- // want to write items into the array, that's fine! The fastest
47
- // way to turn a read-only Object to a writeable one in ES6 seems
48
- // to be to use object-spread. (Going off this benchmark:
49
- // https://thecodebarbarian.com/object-assign-vs-object-spread.html)
50
- _extends({}, blob)) : err('Must be an object');
51
- });
52
- /**
53
- * Accepts objects with fields matching the given decoders. Extra fields that
54
- * exist on the input object are ignored and will not be returned.
55
- */
56
-
57
- exports.pojo = pojo;
18
+ return blob !== null && blob !== undefined && typeof blob === 'object' && Object.prototype.toString.call(blob) === '[object Object]' ? ok(blob) : err('Must be an object')
19
+ })
20
+
21
+ exports.pojo = pojo
58
22
 
59
23
  function object(decodersByKey) {
60
- // Compute this set at decoder definition time
61
- var knownKeys = new Set(Object.keys(decodersByKey));
24
+ var knownKeys = new Set(Object.keys(decodersByKey))
62
25
  return pojo.then(function (plainObj, ok, err) {
63
- var actualKeys = new Set(Object.keys(plainObj)); // At this point, "missingKeys" will also include all fields that may
64
- // validly be optional. We'll let the underlying decoder decide and
65
- // remove the key from this missing set if the decoder accepts the
66
- // value.
67
-
68
- var missingKeys = subtract(knownKeys, actualKeys);
69
- var record = {};
70
- var errors = null;
26
+ var actualKeys = new Set(Object.keys(plainObj))
27
+
28
+ var missingKeys = (0, _utils.subtract)(knownKeys, actualKeys)
29
+ var record = {}
30
+ var errors = null
71
31
  Object.keys(decodersByKey).forEach(function (key) {
72
- var decoder = decodersByKey[key];
73
- var rawValue = plainObj[key];
74
- var result = decoder.decode(rawValue);
32
+ var decoder = decodersByKey[key]
33
+ var rawValue = plainObj[key]
34
+ var result = decoder.decode(rawValue)
75
35
 
76
36
  if (result.ok) {
77
- var value = result.value;
37
+ var value = result.value
78
38
 
79
39
  if (value !== undefined) {
80
- record[key] = value;
81
- } // If this succeeded, remove the key from the missing keys
82
- // tracker
83
-
40
+ record[key] = value
41
+ }
84
42
 
85
- missingKeys["delete"](key);
43
+ missingKeys['delete'](key)
86
44
  } else {
87
- var ann = result.error; // Keep track of the annotation, but don't return just yet. We
88
- // want to collect more error information.
45
+ var ann = result.error
89
46
 
90
47
  if (rawValue === undefined) {
91
- // Explicitly add it to the missing set if the value is
92
- // undefined. This covers explicit undefineds to be
93
- // treated the same as implicit undefineds (aka missing
94
- // keys).
95
- missingKeys.add(key);
48
+ missingKeys.add(key)
96
49
  } else {
97
50
  if (errors === null) {
98
- errors = {};
51
+ errors = {}
99
52
  }
100
53
 
101
- errors[key] = ann;
54
+ errors[key] = ann
102
55
  }
103
56
  }
104
- }); // Deal with errors now. There are two classes of errors we want to
105
- // report. First of all, we want to report any inline errors in this
106
- // object. Lastly, any fields that are missing should be annotated on
107
- // the outer object itself.
57
+ })
108
58
 
109
59
  if (errors || missingKeys.size > 0) {
110
- var objAnn = (0, _annotate.annotateObject)(plainObj);
60
+ var objAnn = (0, _annotate.annotateObject)(plainObj)
111
61
 
112
62
  if (errors) {
113
- objAnn = (0, _annotate.merge)(objAnn, errors);
63
+ objAnn = (0, _annotate.merge)(objAnn, errors)
114
64
  }
115
65
 
116
66
  if (missingKeys.size > 0) {
117
- var errMsg = Array.from(missingKeys).map(function (key) {
118
- return "\"" + key + "\"";
119
- }).join(', ');
120
- var pluralized = missingKeys.size > 1 ? 'keys' : 'key';
121
- objAnn = (0, _annotate.updateText)(objAnn, "Missing " + pluralized + ": " + errMsg);
67
+ var errMsg = Array.from(missingKeys)
68
+ .map(function (key) {
69
+ return '"' + key + '"'
70
+ })
71
+ .join(', ')
72
+ var pluralized = missingKeys.size > 1 ? 'keys' : 'key'
73
+ objAnn = (0, _annotate.updateText)(objAnn, 'Missing ' + pluralized + ': ' + errMsg)
122
74
  }
123
75
 
124
- return err(objAnn);
76
+ return err(objAnn)
125
77
  }
126
78
 
127
- return ok(record);
128
- });
79
+ return ok(record)
80
+ })
129
81
  }
130
- /**
131
- * Like `object()`, but will reject inputs that contain extra fields that are
132
- * not specified explicitly.
133
- */
134
-
135
82
 
136
83
  function exact(decodersByKey) {
137
- // Compute this set at decoder definition time
138
- var allowedKeys = new Set(Object.keys(decodersByKey)); // Check the inputted object for any unexpected extra keys
84
+ var allowedKeys = new Set(Object.keys(decodersByKey))
139
85
 
140
86
  var checked = pojo.reject(function (plainObj) {
141
- var actualKeys = new Set(Object.keys(plainObj));
142
- var extraKeys = subtract(actualKeys, allowedKeys);
143
- return extraKeys.size > 0 ? "Unexpected extra keys: " + Array.from(extraKeys).join(', ') : // Don't reject
144
- null;
145
- }); // Defer to the "object" decoder for doing the real decoding work. Since
146
- // we made sure there are no superfluous keys in this structure, it's now
147
- // safe to force-cast it to an $Exact<> type.
148
-
149
- return checked.then(object(decodersByKey).decode);
150
- }
151
- /**
152
- * Like `object()`, but will pass through any extra fields on the input object
153
- * unvalidated that will thus be of `unknown` type statically.
154
- */
87
+ var actualKeys = new Set(Object.keys(plainObj))
88
+ var extraKeys = (0, _utils.subtract)(actualKeys, allowedKeys)
89
+ return extraKeys.size > 0 ? 'Unexpected extra keys: ' + Array.from(extraKeys).join(', ') : null
90
+ })
155
91
 
92
+ return checked.then(object(decodersByKey).decode)
93
+ }
156
94
 
157
95
  function inexact(decodersByKey) {
158
96
  return pojo.then(function (plainObj) {
159
- var allkeys = new Set(Object.keys(plainObj));
97
+ var allkeys = new Set(Object.keys(plainObj))
160
98
  var decoder = object(decodersByKey).transform(function (safepart) {
161
- var safekeys = new Set(Object.keys(decodersByKey)); // To account for hard-coded keys that aren't part of the input
99
+ var safekeys = new Set(Object.keys(decodersByKey))
162
100
 
163
101
  safekeys.forEach(function (k) {
164
- return allkeys.add(k);
165
- });
166
- var rv = {};
102
+ return allkeys.add(k)
103
+ })
104
+ var rv = {}
167
105
  allkeys.forEach(function (k) {
168
106
  if (safekeys.has(k)) {
169
- var value = safepart[k];
107
+ var value = safepart[k]
170
108
 
171
109
  if (value !== undefined) {
172
- rv[k] = value;
110
+ rv[k] = value
173
111
  }
174
112
  } else {
175
- rv[k] = plainObj[k];
113
+ rv[k] = plainObj[k]
176
114
  }
177
- });
178
- return rv;
179
- });
180
- return decoder.decode(plainObj);
181
- });
115
+ })
116
+ return rv
117
+ })
118
+ return decoder.decode(plainObj)
119
+ })
182
120
  }
183
- /**
184
- * Accepts objects where all values match the given decoder, and returns the
185
- * result as a `{ [string]: T }`.
186
- *
187
- * The main difference between `object()` and `dict()` is that you'd typically
188
- * use `object()` if this is a record-like object, where all field names are
189
- * known and the values are heterogeneous. Whereas with `dict()` the keys are
190
- * typically dynamic and the values homogeneous, like in a dictionary,
191
- * a lookup table, or a cache.
192
- */
193
-
194
121
 
195
122
  function dict(decoder) {
196
123
  return pojo.then(function (plainObj, ok, err) {
197
- var rv = {};
198
- var errors = null;
124
+ var rv = {}
125
+ var errors = null
199
126
  Object.keys(plainObj).forEach(function (key) {
200
- var value = plainObj[key];
201
- var result = decoder.decode(value);
127
+ var value = plainObj[key]
128
+ var result = decoder.decode(value)
202
129
 
203
130
  if (result.ok) {
204
131
  if (errors === null) {
205
- rv[key] = result.value;
132
+ rv[key] = result.value
206
133
  }
207
134
  } else {
208
- rv = {}; // Clear the success value so it can get garbage collected early
135
+ rv = {}
209
136
 
210
137
  if (errors === null) {
211
- errors = {};
138
+ errors = {}
212
139
  }
213
140
 
214
- errors[key] = result.error;
141
+ errors[key] = result.error
215
142
  }
216
- });
143
+ })
217
144
 
218
145
  if (errors !== null) {
219
- return err((0, _annotate.merge)((0, _annotate.annotateObject)(plainObj), errors));
146
+ return err((0, _annotate.merge)((0, _annotate.annotateObject)(plainObj), errors))
220
147
  } else {
221
- return ok(rv);
148
+ return ok(rv)
222
149
  }
223
- });
150
+ })
224
151
  }
225
- /**
226
- * Similar to `dict()`, but returns the result as a `Map<string, T>` (an [ES6
227
- * Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))
228
- * instead.
229
- */
230
-
231
152
 
232
153
  function mapping(decoder) {
233
154
  return dict(decoder).transform(function (obj) {
234
- return new Map( // This is effectively Object.entries(obj), but in a way that Flow
235
- // will know the types are okay
236
- Object.keys(obj).map(function (key) {
237
- return [key, obj[key]];
238
- }));
239
- });
240
- }
155
+ return new Map(
156
+ Object.keys(obj).map(function (key) {
157
+ return [key, obj[key]]
158
+ })
159
+ )
160
+ })
161
+ }
@@ -2,20 +2,11 @@
2
2
 
3
3
  import { annotateObject, merge, updateText } from '../annotate';
4
4
  import { define } from '../Decoder';
5
+ import { subtract } from '../_utils';
5
6
  import type { Annotation } from '../annotate';
6
7
  import type { _Any as AnyDecoder } from '../_utils';
7
8
  import type { Decoder, DecodeResult } from '../Decoder';
8
9
 
9
- function subtract(xs: Set<string>, ys: Set<string>): Set<string> {
10
- const result = new Set();
11
- xs.forEach((x) => {
12
- if (!ys.has(x)) {
13
- result.add(x);
14
- }
15
- });
16
- return result;
17
- }
18
-
19
10
  /**
20
11
  * Accepts any "plain old JavaScript object", but doesn't validate its keys or
21
12
  * values further.
@@ -43,7 +34,8 @@ export const pojo: Decoder<{| [string]: mixed |}> = define((blob, ok, err) =>
43
34
  // way to turn a read-only Object to a writeable one in ES6 seems
44
35
  // to be to use object-spread. (Going off this benchmark:
45
36
  // https://thecodebarbarian.com/object-assign-vs-object-spread.html)
46
- { ...blob },
37
+ // $FlowFixMe[incompatible-variance]
38
+ blob,
47
39
  )
48
40
  : err('Must be an object'),
49
41
  );
@@ -192,7 +184,7 @@ export function inexact<O: { +[field: string]: AnyDecoder }>(
192
184
 
193
185
  /**
194
186
  * Accepts objects where all values match the given decoder, and returns the
195
- * result as a `{ [string]: T }`.
187
+ * result as a `Record<string, T>`.
196
188
  *
197
189
  * The main difference between `object()` and `dict()` is that you'd typically
198
190
  * use `object()` if this is a record-like object, where all field names are