decoders 2.0.0-beta4 → 2.0.0-beta8

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.
Files changed (132) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/NotSupportedTSVersion.d.ts +1 -0
  3. package/README.md +728 -343
  4. package/_guard.d.ts +7 -0
  5. package/_guard.js +2 -6
  6. package/_guard.js.flow +3 -3
  7. package/{_esm/_guard.js → _guard.mjs} +3 -3
  8. package/_types.d.ts +13 -0
  9. package/{_esm/_types.js → _types.mjs} +0 -0
  10. package/_utils.d.ts +10 -0
  11. package/{_esm/_utils.js → _utils.mjs} +0 -0
  12. package/annotate.d.ts +62 -0
  13. package/{_esm/annotate.js → annotate.mjs} +0 -0
  14. package/core/_helpers.d.ts +79 -0
  15. package/core/array.d.ts +5 -0
  16. package/core/array.js +7 -11
  17. package/core/array.js.flow +6 -9
  18. package/{_esm/core/array.js → core/array.mjs} +9 -9
  19. package/core/boolean.d.ts +5 -0
  20. package/core/boolean.js +4 -8
  21. package/core/boolean.js.flow +3 -5
  22. package/{_esm/core/boolean.js → core/boolean.mjs} +6 -6
  23. package/core/composition.d.ts +14 -0
  24. package/core/composition.js +9 -11
  25. package/core/composition.js.flow +13 -8
  26. package/{_esm/core/composition.js → core/composition.mjs} +10 -8
  27. package/core/constants.d.ts +11 -0
  28. package/core/constants.js +6 -10
  29. package/core/constants.js.flow +7 -9
  30. package/{_esm/core/constants.js → core/constants.mjs} +7 -7
  31. package/core/date.d.ts +4 -0
  32. package/core/date.js +3 -7
  33. package/core/date.js.flow +2 -4
  34. package/{_esm/core/date.js → core/date.mjs} +6 -6
  35. package/core/describe.d.ts +3 -0
  36. package/core/describe.js +2 -6
  37. package/core/describe.js.flow +2 -2
  38. package/{_esm/core/describe.js → core/describe.mjs} +3 -3
  39. package/core/dispatch.d.ts +8 -0
  40. package/core/dispatch.js +9 -13
  41. package/core/dispatch.js.flow +8 -8
  42. package/{_esm/core/dispatch.js → core/dispatch.mjs} +10 -10
  43. package/core/either.d.ts +61 -0
  44. package/core/either.js +7 -11
  45. package/core/either.js.flow +6 -6
  46. package/{_esm/core/either.js → core/either.mjs} +8 -8
  47. package/core/fail.d.ts +3 -0
  48. package/core/fail.js +2 -6
  49. package/core/fail.js.flow +2 -2
  50. package/{_esm/core/fail.js → core/fail.mjs} +3 -3
  51. package/core/instanceOf.d.ts +3 -0
  52. package/core/instanceOf.js +2 -6
  53. package/core/instanceOf.js.flow +3 -3
  54. package/core/instanceOf.mjs +8 -0
  55. package/core/json.d.ts +11 -0
  56. package/core/json.mjs +15 -0
  57. package/core/lazy.d.ts +3 -0
  58. package/{_esm/core/lazy.js → core/lazy.mjs} +0 -0
  59. package/core/mapping.d.ts +6 -0
  60. package/core/mapping.js +23 -23
  61. package/core/mapping.js.flow +25 -17
  62. package/{_esm/core/mapping.js → core/mapping.mjs} +26 -22
  63. package/core/number.d.ts +6 -0
  64. package/core/number.js +9 -13
  65. package/core/number.js.flow +18 -12
  66. package/core/number.mjs +25 -0
  67. package/core/object.d.ts +33 -0
  68. package/core/object.js +7 -11
  69. package/core/object.js.flow +7 -7
  70. package/{_esm/core/object.js → core/object.mjs} +9 -9
  71. package/core/optional.d.ts +5 -0
  72. package/core/optional.js +4 -8
  73. package/core/optional.js.flow +3 -3
  74. package/{_esm/core/optional.js → core/optional.mjs} +6 -6
  75. package/core/string.d.ts +10 -0
  76. package/core/string.js +18 -48
  77. package/core/string.js.flow +16 -39
  78. package/core/string.mjs +49 -0
  79. package/core/tuple.d.ts +30 -0
  80. package/core/tuple.js +12 -8
  81. package/core/tuple.js.flow +25 -29
  82. package/{_esm/core/tuple.js → core/tuple.mjs} +16 -12
  83. package/format.d.ts +4 -0
  84. package/{format/inline.js → format.js} +6 -1
  85. package/{_esm/format/inline.js.flow → format.js.flow} +6 -2
  86. package/{_esm/format/inline.js → format.mjs} +4 -1
  87. package/index.d.ts +43 -0
  88. package/index.js +3 -2
  89. package/index.js.flow +2 -2
  90. package/{_esm/index.js → index.mjs} +19 -19
  91. package/package.json +15 -3
  92. package/result.d.ts +39 -0
  93. package/result.js +3 -78
  94. package/result.js.flow +4 -76
  95. package/{_esm/result.js → result.mjs} +3 -64
  96. package/_esm/_guard.js.flow +0 -20
  97. package/_esm/_types.js.flow +0 -20
  98. package/_esm/_utils.js.flow +0 -97
  99. package/_esm/annotate.js.flow +0 -218
  100. package/_esm/core/array.js.flow +0 -103
  101. package/_esm/core/boolean.js.flow +0 -29
  102. package/_esm/core/composition.js.flow +0 -43
  103. package/_esm/core/constants.js.flow +0 -46
  104. package/_esm/core/date.js.flow +0 -40
  105. package/_esm/core/describe.js.flow +0 -17
  106. package/_esm/core/dispatch.js.flow +0 -58
  107. package/_esm/core/either.js.flow +0 -151
  108. package/_esm/core/fail.js.flow +0 -12
  109. package/_esm/core/instanceOf.js +0 -8
  110. package/_esm/core/instanceOf.js.flow +0 -20
  111. package/_esm/core/json.js +0 -15
  112. package/_esm/core/json.js.flow +0 -28
  113. package/_esm/core/lazy.js.flow +0 -15
  114. package/_esm/core/mapping.js.flow +0 -54
  115. package/_esm/core/number.js +0 -25
  116. package/_esm/core/number.js.flow +0 -34
  117. package/_esm/core/object.js.flow +0 -203
  118. package/_esm/core/optional.js.flow +0 -41
  119. package/_esm/core/string.js +0 -76
  120. package/_esm/core/string.js.flow +0 -82
  121. package/_esm/core/tuple.js.flow +0 -215
  122. package/_esm/format/index.js +0 -2
  123. package/_esm/format/index.js.flow +0 -4
  124. package/_esm/format/short.js +0 -4
  125. package/_esm/format/short.js.flow +0 -8
  126. package/_esm/index.js.flow +0 -63
  127. package/_esm/result.js.flow +0 -170
  128. package/format/index.js +0 -12
  129. package/format/index.js.flow +0 -4
  130. package/format/inline.js.flow +0 -122
  131. package/format/short.js +0 -10
  132. package/format/short.js.flow +0 -8
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/decoders.svg)](https://www.npmjs.com/package/decoders)
4
4
  [![Build Status](https://github.com/nvie/decoders/workflows/test/badge.svg)](https://github.com/nvie/decoders/actions)
5
- [![Coverage Status](https://img.shields.io/coveralls/nvie/decoders/master.svg)](https://coveralls.io/github/nvie/decoders?branch=master)
5
+ [![Coverage Status](https://img.shields.io/coveralls/nvie/decoders/main.svg)](https://coveralls.io/github/nvie/decoders?branch=main)
6
6
  [![Minified Size](https://badgen.net/bundlephobia/minzip/decoders)](https://bundlephobia.com/result?p=decoders)
7
7
 
8
8
  Elegant and battle-tested validation library for type-safe input data for TypeScript and
@@ -79,220 +79,419 @@ The decoders package consists of a few building blocks:
79
79
  ### Primitives
80
80
 
81
81
  <a name="number" href="#number">#</a> <b>number</b>: <i>Decoder&lt;number&gt;</i>
82
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/number.js 'Source')
82
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/number.js 'Source')
83
83
 
84
- Returns a decoder capable of decoding finite (!) numbers (integer or float values). This
85
- means that values like `NaN`, or positive and negative `Infinity` are not considered valid
86
- numbers.
84
+ Accepts only finite numbers (integer or float values). This means that values like `NaN`,
85
+ or positive and negative `Infinity` are not considered valid numbers.
87
86
 
87
+ <!-- prettier-ignore-start -->
88
88
  ```javascript
89
- const mydecoder = guard(number);
90
- mydecoder(123) === 123;
91
- mydecoder(-3.14) === -3.14;
92
- mydecoder(NaN); // DecodeError
93
- mydecoder('not a number'); // DecodeError
89
+ const verify = guard(number);
90
+
91
+ // 👍
92
+ verify(123) === 123;
93
+ verify(-3.14) === -3.14;
94
+
95
+ // 👎
96
+ verify(Infinity); // throws
97
+ verify(NaN); // throws
98
+ verify('not a number'); // throws
94
99
  ```
100
+ <!-- prettier-ignore-end -->
95
101
 
96
102
  ---
97
103
 
98
104
  <a name="integer" href="#integer">#</a> <b>integer</b>: <i>Decoder&lt;integer&gt;</i>
99
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/number.js 'Source')
105
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/number.js 'Source')
100
106
 
101
- Like `number`, but only decodes values that are whole numbers.
107
+ Like `number`, but only accepts values that are whole numbers.
102
108
 
109
+ <!-- prettier-ignore-start -->
103
110
  ```javascript
104
- const mydecoder = guard(integer);
105
- mydecoder(123) === 123;
106
- mydecoder(-3.14); // DecodeError: floats aren't valid integers
107
- mydecoder(NaN); // DecodeError
108
- mydecoder('not a integer'); // DecodeError
111
+ const verify = guard(integer);
112
+
113
+ // 👍
114
+ verify(123) === 123;
115
+
116
+ // 👎
117
+ verify(-3.14); // throws
118
+ verify(Infinity); // throws
119
+ verify(NaN); // throws
120
+ verify('not a integer'); // throws
109
121
  ```
122
+ <!-- prettier-ignore-end -->
123
+
124
+ ---
125
+
126
+ <a name="positiveNumber" href="#positiveNumber">#</a> <b>positiveNumber</b>:
127
+ <i>Decoder&lt;number&gt;</i>
128
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/number.js 'Source')
129
+
130
+ Accepts only positive finite numbers (integer or float values).
131
+
132
+ <!-- prettier-ignore-start -->
133
+ ```javascript
134
+ const verify = guard(positiveNumber);
135
+
136
+ // 👍
137
+ verify(123) === 123;
138
+
139
+ // 👎
140
+ verify(-42); // throws
141
+ verify(3.14); // throws
142
+ verify(Infinity); // throws
143
+ verify(NaN); // throws
144
+ verify('not a number'); // throws
145
+ ```
146
+ <!-- prettier-ignore-end -->
147
+
148
+ ---
149
+
150
+ <a name="positiveInteger" href="#positiveInteger">#</a> <b>positiveInteger</b>:
151
+ <i>Decoder&lt;number&gt;</i>
152
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/number.js 'Source')
153
+
154
+ Accepts only positive finite integers.
155
+
156
+ <!-- prettier-ignore-start -->
157
+ ```javascript
158
+ const verify = guard(positiveInteger);
159
+
160
+ // 👍
161
+ verify(123) === 123;
162
+
163
+ // 👎
164
+ verify(-3); // throws
165
+ verify(3.14); // throws
166
+ verify(Infinity); // throws
167
+ verify(NaN); // throws
168
+ verify('not a number'); // throws
169
+ ```
170
+ <!-- prettier-ignore-end -->
110
171
 
111
172
  ---
112
173
 
113
174
  <a name="string" href="#string">#</a> <b>string</b>: <i>Decoder&lt;string&gt;</i>
114
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/string.js 'Source')
175
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/string.js 'Source')
115
176
 
116
- Returns a decoder capable of decoding string values.
177
+ Accepts only string values.
117
178
 
179
+ <!-- prettier-ignore-start -->
118
180
  ```javascript
119
- const mydecoder = guard(string);
120
- mydecoder('hello world') === 'hello world';
121
- mydecoder(123); // DecodeError
181
+ const verify = guard(string);
182
+
183
+ // 👍
184
+ verify('hello world') === 'hello world';
185
+ verify('🚀') === '🚀';
186
+ verify('') === '';
187
+
188
+ // 👎
189
+ verify(123); // throws
190
+ verify(true); // throws
191
+ verify(null); // throws
122
192
  ```
193
+ <!-- prettier-ignore-end -->
123
194
 
124
195
  ---
125
196
 
126
197
  <a name="nonEmptyString" href="#nonEmptyString">#</a> <b>nonEmptyString</b>:
127
198
  <i>Decoder&lt;string&gt;</i>
128
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/string.js 'Source')
199
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/string.js 'Source')
129
200
 
130
- Like `string`, but will fail on inputs with only whitespace (or the empty string).
201
+ Like `string`, but will reject the empty string, or strings containing only whitespace.
131
202
 
203
+ <!-- prettier-ignore-start -->
132
204
  ```javascript
133
- const mydecoder = guard(nonEmptyString);
134
- mydecoder('hello world') === 'hello world';
135
- mydecoder(123); // DecodeError
136
- mydecoder(' '); // DecodeError
137
- mydecoder(''); // DecodeError
205
+ const verify = guard(nonEmptyString);
206
+
207
+ // 👍
208
+ verify('hello world') === 'hello world';
209
+ verify('🚀') === '🚀';
210
+
211
+ // 👎
212
+ verify(123); // throws
213
+ verify(' '); // throws
214
+ verify(''); // throws
138
215
  ```
216
+ <!-- prettier-ignore-end -->
139
217
 
140
218
  ---
141
219
 
142
220
  <a name="regex" href="#regex">#</a> <b>regex</b>(): <i>Decoder&lt;string&gt;</i>
143
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/string.js 'Source')
221
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/string.js 'Source')
144
222
 
145
- Returns a decoder capable of decoding string values that match the given regular
146
- expression.
223
+ Accepts only string values that match the given regular expression.
147
224
 
225
+ <!-- prettier-ignore-start -->
148
226
  ```javascript
149
- const mydecoder = guard(regex(/^[0-9]+$/));
150
- mydecoder('12345') === '12345';
151
- mydecoder('foo'); // DecodeError
227
+ const verify = guard(regex(/^[0-9][0-9]+$/));
228
+
229
+ // 👍
230
+ verify('42') === '42';
231
+ verify('83401648364738') === '83401648364738';
232
+
233
+ // 👎
234
+ verify(''); // throws
235
+ verify('1'); // throws
236
+ verify('foo'); // throws
152
237
  ```
238
+ <!-- prettier-ignore-end -->
153
239
 
154
240
  ---
155
241
 
156
242
  <a name="email" href="#email">#</a> <b>email</b>: <i>Decoder&lt;string&gt;</i>
157
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/string.js 'Source')
243
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/string.js 'Source')
244
+
245
+ Accepts only strings that are syntactically valid email addresses. (This will not mean
246
+ that the email address actually exist.)
247
+
248
+ <!-- prettier-ignore-start -->
249
+ ```javascript
250
+ const verify = guard(email);
251
+
252
+ // 👍
253
+ verify('alice@acme.org') === 'alice@acme.org';
254
+
255
+ // 👎
256
+ verify('foo'); // throws
257
+ verify('@acme.org'); // throws
258
+ verify('alice @ acme.org'); // throws
259
+ ```
260
+ <!-- prettier-ignore-end -->
261
+
262
+ ---
263
+
264
+ <a name="url" href="#url">#</a> <b>url</b>: <i>Decoder&lt;URL&gt;</i>
265
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/string.js 'Source')
158
266
 
159
- Returns a decoder capable of decoding email addresses (using a regular expression).
267
+ Accepts strings that are valid URLs, returns the value as a URL instance.
160
268
 
269
+ <!-- prettier-ignore-start -->
161
270
  ```javascript
162
- const mydecoder = guard(email);
163
- mydecoder('foo'); // DecodeError
164
- mydecoder('alice@acme.org') === 'alice@acme.org';
271
+ const verify = guard(url);
272
+
273
+ // 👍
274
+ verify('http://nvie.com') === new URL('http://nvie.com/');
275
+ verify('https://nvie.com') === new URL('https://nvie.com/');
276
+ verify('git+ssh://user@github.com/foo/bar.git') === new URL('git+ssh://user@github.com/foo/bar.git');
277
+
278
+ // 👎
279
+ verify('foo'); // throws
280
+ verify('@acme.org'); // throws
281
+ verify('alice @ acme.org'); // throws
282
+ verify('/search?q=foo'); // throws
283
+ ```
284
+ <!-- prettier-ignore-end -->
285
+
286
+ ---
287
+
288
+ <a name="httpsUrl" href="#httpsUrl">#</a> <b>httpsUrl</b>: <i>Decoder&lt;URL&gt;</i>
289
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/string.js 'Source')
290
+
291
+ Accepts strings that are valid URLs, but only HTTPS ones. Returns the value as a URL
292
+ instance.
293
+
294
+ <!-- prettier-ignore-start -->
295
+ ```javascript
296
+ const verify = guard(httpsUrl);
297
+
298
+ // 👍
299
+ verify('https://nvie.com:443') === new URL('https://nvie.com/');
300
+
301
+ // 👎
302
+ verify('http://nvie.com'); // throws, not HTTPS
303
+ verify('git+ssh://user@github.com/foo/bar.git'); // throws, not HTTPS
304
+ ```
305
+ <!-- prettier-ignore-end -->
306
+
307
+ **Tip!** If you need to limit URLs to different protocols than HTTP, you can do as the
308
+ HTTPS decoder is implemented: as a predicate on top of a regular `url` decoder.
309
+
310
+ ```typescript
311
+ import { predicate, url } from 'decoders';
312
+
313
+ const gitUrl: Decoder<URL> = predicate(
314
+ url,
315
+ (value) => value.protocol === 'git:',
316
+ 'Must be a git:// URL',
317
+ );
165
318
  ```
166
319
 
167
320
  ---
168
321
 
169
322
  <a name="boolean" href="#boolean">#</a> <b>boolean</b>: <i>Decoder&lt;boolean&gt;</i>
170
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/boolean.js 'Source')
323
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/boolean.js 'Source')
171
324
 
172
- Returns a decoder capable of decoding boolean values.
325
+ Accepts only boolean values.
173
326
 
327
+ <!-- prettier-ignore-start -->
174
328
  ```javascript
175
- const mydecoder = guard(boolean);
176
- mydecoder(false) === false;
177
- mydecoder(true) === true;
178
- mydecoder(undefined); // DecodeError
179
- mydecoder('hello world'); // DecodeError
180
- mydecoder(123); // DecodeError
329
+ const verify = guard(boolean);
330
+
331
+ // 👍
332
+ verify(false) === false;
333
+ verify(true) === true;
334
+
335
+ // 👎
336
+ verify(undefined); // throws
337
+ verify('hello world'); // throws
338
+ verify(123); // throws
181
339
  ```
340
+ <!-- prettier-ignore-end -->
182
341
 
183
342
  ---
184
343
 
185
344
  <a name="truthy" href="#truthy">#</a> <b>truthy</b>: <i>Decoder&lt;boolean&gt;</i>
186
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/boolean.js 'Source')
345
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/boolean.js 'Source')
187
346
 
188
- Returns a decoder capable of decoding any input value to its "truthy value".
347
+ Accepts any value and will return its "truth" value. Will never reject.
189
348
 
190
349
  ```javascript
191
- const mydecoder = guard(truthy);
192
- mydecoder(false) === false;
193
- mydecoder(true) === true;
194
- mydecoder(undefined) === false;
195
- mydecoder('hello world') === true;
196
- mydecoder('false') === true;
197
- mydecoder(0) === false;
198
- mydecoder(1) === true;
199
- mydecoder(null) === false;
350
+ const verify = guard(truthy);
351
+
352
+ // 👍
353
+ verify(false) === false;
354
+ verify(true) === true;
355
+ verify(undefined) === false;
356
+ verify('hello world') === true;
357
+ verify('false') === true;
358
+ verify(0) === false;
359
+ verify(1) === true;
360
+ verify(null) === false;
361
+
362
+ // 👎
363
+ // This decoder will never reject an input
200
364
  ```
201
365
 
202
366
  ---
203
367
 
204
368
  <a name="numericBoolean" href="#numericBoolean">#</a> <b>numericBoolean</b>:
205
369
  <i>Decoder&lt;boolean&gt;</i>
206
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/boolean.js 'Source')
370
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/boolean.js 'Source')
207
371
 
208
- Returns a decoder capable of decoding numbers to their boolean representation.
372
+ Accepts only number values, but return their boolean representation.
209
373
 
374
+ <!-- prettier-ignore-start -->
210
375
  ```javascript
211
- const mydecoder = guard(numericBoolean);
212
- mydecoder(-1) === true;
213
- mydecoder(0) === false;
214
- mydecoder(123) === true;
215
- mydecoder(false); // DecodeError
216
- mydecoder(true); // DecodeError
217
- mydecoder(undefined); // DecodeError
218
- mydecoder('hello'); // DecodeError
376
+ const verify = guard(numericBoolean);
377
+
378
+ // 👍
379
+ verify(-1) === true;
380
+ verify(0) === false;
381
+ verify(123) === true;
382
+
383
+ // 👎
384
+ verify(false); // throws
385
+ verify(true); // throws
386
+ verify(undefined); // throws
387
+ verify('hello'); // throws
219
388
  ```
389
+ <!-- prettier-ignore-end -->
220
390
 
221
391
  ---
222
392
 
223
393
  <a name="date" href="#date">#</a> <b>date</b>: <i>Decoder&lt;Date&gt;</i>
224
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/date.js 'Source')
394
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/date.js 'Source')
225
395
 
226
- Returns a decoder capable of decoding
227
- [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
228
- values.
396
+ Accepts only JavaScript [Date][date-api] values.
229
397
 
398
+ <!-- prettier-ignore-start -->
230
399
  ```javascript
400
+ const verify = guard(date);
231
401
  const now = new Date();
232
- const mydecoder = guard(date);
233
- mydecoder(now) === now;
234
- mydecoder(123); // DecodeError
235
- mydecoder('hello'); // DecodeError
402
+
403
+ // 👍
404
+ verify(now) === now;
405
+
406
+ // 👎
407
+ verify(123); // throws
408
+ verify('hello'); // throws
236
409
  ```
410
+ <!-- prettier-ignore-end -->
237
411
 
238
412
  ---
239
413
 
240
414
  <a name="iso8601" href="#iso8601">#</a> <b>iso8601</b>: <i>Decoder&lt;Date&gt;</i>
241
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/date.js 'Source')
415
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/date.js 'Source')
242
416
 
243
- Returns a decoder capable of decoding
244
- [ISO8601](https://en.wikipedia.org/wiki/ISO_8601)-formatted date strings. This is very
245
- useful for working with dates in APIs: serialize them as `.toISOString()` when sending,
246
- decode them as `iso8601` when receiving.
417
+ Accepts only [ISO8601][iso8601-fmt]-formatted strings. This is very useful for working
418
+ with dates in APIs: serialize them as `.toISOString()` when sending, decode them with
419
+ `iso8601` when receiving.
247
420
 
248
- **NOTE:** This decoder reads a _string_, but returns a _Date_ instance.
421
+ **NOTE:** This decoder accepts _strings_, but returns _Date_ instances.
249
422
 
423
+ <!-- prettier-ignore-start -->
250
424
  ```javascript
251
- const mydecoder = guard(iso8601);
252
- mydecoder('2020-06-01T12:00:00Z'); // new Date('2020-06-01T12:00:00Z')
253
- mydecoder('2020-06-01'); // DecodeError
254
- mydecoder('hello'); // DecodeError
255
- mydecoder(123); // DecodeError
425
+ const verify = guard(iso8601);
426
+
427
+ // 👍
428
+ verify('2020-06-01T12:00:00Z'); // ≈ new Date('2020-06-01T12:00:00Z')
429
+
430
+ // 👎
431
+ verify('2020-06-01'); // throws
432
+ verify('hello'); // throws
433
+ verify(123); // throws
434
+ verify(new Date()); // throws (does not accept dates)
256
435
  ```
436
+ <!-- prettier-ignore-end -->
257
437
 
258
438
  ---
259
439
 
260
440
  <a name="null_" href="#null_">#</a> <b>null\_</b>: <i>Decoder&lt;null&gt;</i>
261
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/constants.js 'Source')
441
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/constants.js 'Source')
262
442
 
263
- Returns a decoder capable of decoding the constant value `null`.
443
+ Accepts only the literal `null` value.
264
444
 
445
+ <!-- prettier-ignore-start -->
265
446
  ```javascript
266
- const mydecoder = guard(null_);
267
- mydecoder(null) === null;
268
- mydecoder(false); // DecodeError
269
- mydecoder(undefined); // DecodeError
270
- mydecoder('hello world'); // DecodeError
447
+ const verify = guard(null_);
448
+
449
+ // 👍
450
+ verify(null) === null;
451
+
452
+ // 👎
453
+ verify(false); // throws
454
+ verify(undefined); // throws
455
+ verify('hello world'); // throws
271
456
  ```
457
+ <!-- prettier-ignore-end -->
272
458
 
273
459
  ---
274
460
 
275
461
  <a name="undefined_" href="#undefined_">#</a> <b>undefined\_</b>:
276
462
  <i>Decoder&lt;void&gt;</i>
277
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/constants.js 'Source')
463
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/constants.js 'Source')
278
464
 
279
- Returns a decoder capable of decoding the constant value `undefined`.
465
+ Accepts only the literal `undefined` value.
280
466
 
467
+ <!-- prettier-ignore-start -->
281
468
  ```javascript
282
- const mydecoder = guard(undefined_);
283
- mydecoder(undefined) === undefined;
284
- mydecoder(null); // DecodeError
285
- mydecoder(false); // DecodeError
286
- mydecoder('hello world'); // DecodeError
469
+ const verify = guard(undefined_);
470
+
471
+ // 👍
472
+ verify(undefined) === undefined;
473
+
474
+ // 👎
475
+ verify(null); // throws
476
+ verify(false); // throws
477
+ verify('hello world'); // throws
287
478
  ```
479
+ <!-- prettier-ignore-end -->
288
480
 
289
481
  ---
290
482
 
291
483
  <a name="constant" href="#constant">#</a> <b>constant</b><i>&lt;T&gt;</i>(value: T):
292
484
  <i>Decoder&lt;T&gt;</i>
293
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/constants.js 'Source')
485
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/constants.js 'Source')
486
+
487
+ Accepts only the given constant value.
488
+
489
+ For TypeScript, use this syntax:
294
490
 
295
- Returns a decoder capable of decoding just the given constant value.
491
+ ```typescript
492
+ constant('something' as const);
493
+ constant(42 as const);
494
+ ```
296
495
 
297
496
  For Flow, use this syntax:
298
497
 
@@ -303,63 +502,91 @@ constant((42: 42));
303
502
 
304
503
  Example:
305
504
 
505
+ <!-- prettier-ignore-start -->
306
506
  ```typescript
307
- const mydecoder = guard(constant('hello'));
308
- mydecoder('hello') === 'hello';
309
- mydecoder('this breaks'); // DecodeError
310
- mydecoder(false); // DecodeError
311
- mydecoder(undefined); // DecodeError
507
+ const verify = guard(constant('hello' as const));
508
+
509
+ // 👍
510
+ verify('hello') === 'hello';
511
+
512
+ // 👎
513
+ verify('this breaks'); // throws
514
+ verify(false); // throws
515
+ verify(undefined); // throws
312
516
  ```
517
+ <!-- prettier-ignore-end -->
313
518
 
314
519
  ---
315
520
 
316
521
  <a name="hardcoded" href="#hardcoded">#</a> <b>hardcoded</b><i>&lt;T&gt;</i>(value: T):
317
522
  <i>Decoder&lt;T&gt;</i>
318
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/constants.js 'Source')
523
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/constants.js 'Source')
319
524
 
320
- Returns a decoder that will always return the provided value **without looking at the
321
- input**. This is useful to manually add extra fields.
525
+ Accepts any input, completely ignores it, and always returns the provided value. This is
526
+ useful to manually add extra fields to object decoders.
322
527
 
528
+ <!-- prettier-ignore-start -->
323
529
  ```javascript
324
- const mydecoder = guard(hardcoded(2.1));
325
- mydecoder('hello') === 2.1;
326
- mydecoder(false) === 2.1;
327
- mydecoder(undefined) === 2.1;
530
+ const verify = guard(hardcoded(42));
531
+
532
+ // 👍
533
+ verify('hello') === 42;
534
+ verify(false) === 42;
535
+ verify(undefined) === 42;
536
+
537
+ // 👎
538
+ // This decoder will never reject an input
328
539
  ```
540
+ <!-- prettier-ignore-end -->
329
541
 
330
542
  ---
331
543
 
332
544
  <a name="fail" href="#fail">#</a> <b>fail</b>(): <i>Decoder&lt;empty&gt;</i>
333
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/fail.js 'Source')
545
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/fail.js 'Source')
334
546
 
335
- Returns a decoder that will always fail with the given error messages, no matter what the
336
- input. May be useful for explicitly disallowing keys, or for testing purposes.
547
+ Rejects all inputs, and always fails with the given error message. May be useful for
548
+ explicitly disallowing keys, or for testing purposes.
337
549
 
550
+ <!-- prettier-ignore-start -->
338
551
  ```javascript
339
- const mydecoder = guard(object({ a: string, b: optional(fail('Key b has been removed')) })));
340
- mydecoder({ a: 'foo' }) === { a: 'foo' }
341
- mydecoder({ a: 'foo', c: 'bar' }) === { a: 'foo' }
342
- mydecoder({ a: 'foo', b: 'bar' }) // DecodeError
552
+ const verify = guard(object({
553
+ a: string,
554
+ b: optional(fail('Key b has been removed')),
555
+ }));
556
+
557
+ // 👍
558
+ verify({ a: 'foo' }); // ≈ { a: 'foo' };
559
+ verify({ a: 'foo', c: 'bar' }); // ≈ { a: 'foo' };
560
+
561
+ // 👎
562
+ verify({ a: 'foo', b: 'bar' }); // throws
343
563
  ```
564
+ <!-- prettier-ignore-end -->
344
565
 
345
566
  ---
346
567
 
347
- <a name="mixed" href="#mixed">#</a> <b>mixed</b>: <i>Decoder&lt;mixed&gt;</i>
348
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/constants.js 'Source')<br />
349
568
  <a name="unknown" href="#unknown">#</a> <b>unknown</b>: <i>Decoder&lt;unknown&gt;</i>
350
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/constants.js 'Source')
569
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/constants.js 'Source')
570
+ <a name="mixed" href="#mixed">#</a> <b>unknown</b>: <i>Decoder&lt;mixed&gt;</i>
571
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/constants.js 'Source')<br />
351
572
 
352
- Returns a decoder that will simply pass through any input value, never fails. This
353
- effectively returns a `Decoder<mixed>`, which is not that useful. **Use sparingly.**
573
+ Accepts any value and returns it unchanged. Useful for situation in which you don't know
574
+ or expect a specific type. Of course, the downside is that you won't know the type of the
575
+ value statically and you'll have to further refine it yourself.
354
576
 
355
- Same as `unknown` in TypeScript.
577
+ (Unknown is called `mixed` in Flow.)
356
578
 
357
579
  ```javascript
358
- const mydecoder = guard(mixed);
359
- mydecoder('hello') === 'hello';
360
- mydecoder(false) === false;
361
- mydecoder(undefined) === undefined;
362
- mydecoder([1, 2]) === [1, 2];
580
+ const verify = guard(mixed);
581
+
582
+ // 👍
583
+ verify('hello') === 'hello';
584
+ verify(false) === false;
585
+ verify(undefined) === undefined;
586
+ verify([1, 2]) === [1, 2];
587
+
588
+ // 👎
589
+ // This decoder will never reject an input
363
590
  ```
364
591
 
365
592
  ### Compositions
@@ -372,19 +599,24 @@ decoder for arrays of points: `array(pointDecoder)`, which will be of type
372
599
 
373
600
  <a name="optional" href="#optional">#</a>
374
601
  <b>optional</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>): <i>Decoder&lt;T | void&gt;</i>
375
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/optional.js 'Source')
602
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/optional.js 'Source')
376
603
 
377
- Returns a decoder capable of decoding **either a value of type <i>T</i>, or `undefined`**,
378
- provided that you already have a decoder for <i>T</i>.
604
+ Accepts only the literal value `undefined`, or whatever the given decoder accepts.
379
605
 
606
+ <!-- prettier-ignore-start -->
380
607
  ```javascript
381
- const mydecoder = guard(optional(string));
382
- mydecoder('hello') === 'hello';
383
- mydecoder(undefined) === undefined;
384
- mydecoder(null); // DecodeError
385
- mydecoder(0); // DecodeError
386
- mydecoder(42); // DecodeError
608
+ const verify = guard(optional(string));
609
+
610
+ // 👍
611
+ verify('hello') === 'hello';
612
+ verify(undefined) === undefined;
613
+
614
+ // 👎
615
+ verify(null); // throws
616
+ verify(0); // throws
617
+ verify(42); // throws
387
618
  ```
619
+ <!-- prettier-ignore-end -->
388
620
 
389
621
  A typical case where `optional` is useful is in decoding objects with optional fields:
390
622
 
@@ -410,127 +642,185 @@ Which will decode to type:
410
642
 
411
643
  <a name="nullable" href="#nullable">#</a>
412
644
  <b>nullable</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>): <i>Decoder&lt;T | null&gt;</i>
413
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/optional.js 'Source')
645
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/optional.js 'Source')
414
646
 
415
- Returns a decoder capable of decoding **either a value of type <i>T</i>, or `null`**,
416
- provided that you already have a decoder for <i>T</i>.
647
+ Accepts only the literal value `null`, or whatever the given decoder accepts.
417
648
 
649
+ <!-- prettier-ignore-start -->
418
650
  ```javascript
419
- const mydecoder = guard(nullable(string));
420
- mydecoder('hello') === 'hello';
421
- mydecoder(null) === null;
422
- mydecoder(undefined); // DecodeError
423
- mydecoder(0); // DecodeError
424
- mydecoder(42); // DecodeError
651
+ const verify = guard(nullable(string));
652
+
653
+ // 👍
654
+ verify('hello') === 'hello';
655
+ verify(null) === null;
656
+
657
+ // 👎
658
+ verify(undefined); // throws
659
+ verify(0); // throws
660
+ verify(42); // throws
425
661
  ```
662
+ <!-- prettier-ignore-end -->
426
663
 
427
664
  ---
428
665
 
429
666
  <a name="maybe" href="#maybe">#</a> <b>maybe</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>):
430
667
  <i>Decoder&lt;?T&gt;</i>
431
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/optional.js 'Source')
668
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/optional.js 'Source')
432
669
 
433
- Returns a decoder capable of decoding **either a value of type <i>T</i>, or `null`, or
434
- `undefined`**, provided that you already have a decoder for <i>T</i>.
670
+ Accepts only `undefined`, `null`, or whatever the given decoder accepts.
435
671
 
672
+ <!-- prettier-ignore-start -->
436
673
  ```javascript
437
- const mydecoder = guard(maybe(string));
438
- mydecoder('hello') === 'hello';
439
- mydecoder(null) === null;
440
- mydecoder(undefined) === undefined;
441
- mydecoder(0); // DecodeError
442
- mydecoder(42); // DecodeError
674
+ const verify = guard(maybe(string));
675
+
676
+ // 👍
677
+ verify('hello') === 'hello';
678
+ verify(null) === null;
679
+ verify(undefined) === undefined;
680
+
681
+ // 👎
682
+ verify(0); // throws
683
+ verify(42); // throws
443
684
  ```
685
+ <!-- prettier-ignore-end -->
444
686
 
445
687
  ---
446
688
 
447
689
  <a name="array" href="#array">#</a> <b>array</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>):
448
690
  <i>Decoder&lt;Array&lt;T&gt;&gt;</i>
449
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/array.js 'Source')
691
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/array.js 'Source')
450
692
 
451
- Returns a decoder capable of decoding **an array of <i>T</i>'s**, provided that you
452
- already have a decoder for <i>T</i>.
693
+ Accepts only arrays of whatever the given decoder accepts.
453
694
 
695
+ <!-- prettier-ignore-start -->
454
696
  ```javascript
455
- const mydecoder = guard(array(string));
456
- mydecoder(['hello', 'world']) === ['hello', 'world'];
457
- mydecoder(['hello', 1.2]); // DecodeError
697
+ const verify = guard(array(string));
698
+
699
+ // 👍
700
+ verify(['hello', 'world']) === ['hello', 'world'];
701
+
702
+ // 👎
703
+ verify(['hello', 1.2]); // throws
458
704
  ```
705
+ <!-- prettier-ignore-end -->
459
706
 
460
707
  ---
461
708
 
462
709
  <a name="nonEmptyArray" href="#nonEmptyArray">#</a>
463
710
  <b>nonEmptyArray</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>):
464
711
  <i>Decoder&lt;Array&lt;T&gt;&gt;</i>
465
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/array.js 'Source')
712
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/array.js 'Source')
713
+
714
+ Like `array()`, but will reject arrays with 0 elements.
715
+
716
+ <!-- prettier-ignore-start -->
717
+ ```javascript
718
+ const verify = guard(nonEmptyArray(string));
719
+
720
+ // 👍
721
+ verify(['hello', 'world']) === ['hello', 'world'];
722
+
723
+ // 👎
724
+ verify(['hello', 1.2]); // throws
725
+ verify([]); // throws
726
+ ```
727
+ <!-- prettier-ignore-end -->
728
+
729
+ ---
730
+
731
+ <a name="poja" href="#poja">#</a> <b>poja</b>: <i>Decoder&lt;Array&lt;unknown&gt;&gt;</i>
732
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/array.js 'Source')
466
733
 
467
- Like `array()`, but will fail on inputs with 0 elements.
734
+ Accepts any array, but doesn't validate its items further.
468
735
 
736
+ "poja" means "plain old JavaScript array", a play on ["pojo"](#pojo).
737
+
738
+ <!-- prettier-ignore-start -->
469
739
  ```javascript
470
- const mydecoder = guard(nonEmptyArray(string));
471
- mydecoder(['hello', 'world']) === ['hello', 'world'];
472
- mydecoder(['hello', 1.2]); // DecodeError
473
- mydecoder([]); // DecodeError
740
+ const verify = guard(poja);
741
+
742
+ // 👍
743
+ verify([1, 'hi', true]) === [1, 'hi', true];
744
+ verify(['hello', 'world']) === ['hello', 'world'];
745
+ verify([]) === [];
746
+
747
+ // 👎
748
+ verify({}); // throws
749
+ verify('hi'); // throws
474
750
  ```
751
+ <!-- prettier-ignore-end -->
475
752
 
476
753
  ---
477
754
 
478
755
  <a name="tuple1" href="#tuple1">#</a>
479
756
  <b>tuple1</b><i>&lt;T1&gt;</i>(<i>Decoder&lt;T1&gt;</i>): <i>Decoder&lt;[T1]&gt;</i>
480
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/tuple.js 'Source')<br />
757
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/tuple.js 'Source')<br />
481
758
  <a name="tuple2" href="#tuple2">#</a> <b>tuple2</b><i>&lt;T1,
482
759
  T2&gt;</i>(<i>Decoder&lt;T1&gt;</i>, <i>Decoder&lt;T2&gt;</i>): <i>Decoder&lt;[T1,
483
760
  T2]&gt;</i>
484
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/tuple.js 'Source')<br />
761
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/tuple.js 'Source')<br />
485
762
  <a name="tuple3" href="#tuple3">#</a> <b>tuple3</b><i>&lt;T1, T2,
486
763
  T3&gt;</i>(<i>Decoder&lt;T1&gt;</i>, <i>Decoder&lt;T2&gt;</i>, <i>Decoder&lt;T3&gt;</i>):
487
764
  <i>Decoder&lt;[T1, T2, T3]&gt;</i>
488
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/tuple.js 'Source')<br />
765
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/tuple.js 'Source')<br />
489
766
  <a name="tuple4" href="#tuple4">#</a> <b>tuple4</b><i>&lt;T1, T2, T3,
490
767
  T4&gt;</i>(<i>Decoder&lt;T1&gt;</i>, <i>Decoder&lt;T2&gt;</i>, <i>Decoder&lt;T3&gt;</i>,
491
768
  <i>Decoder&lt;T4&gt;</i>): <i>Decoder&lt;[T1, T2, T3, T4]&gt;</i>
492
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/tuple.js 'Source')<br />
769
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/tuple.js 'Source')<br />
493
770
  <a name="tuple5" href="#tuple5">#</a> <b>tuple5</b><i>&lt;T1, T2, T3, T4,
494
771
  T5&gt;</i>(<i>Decoder&lt;T1&gt;</i>, <i>Decoder&lt;T2&gt;</i>, <i>Decoder&lt;T3&gt;</i>,
495
772
  <i>Decoder&lt;T3&gt;</i>, <i>Decoder&lt;T4&gt;</i>, <i>Decoder&lt;T5&gt;</i>):
496
773
  <i>Decoder&lt;[T1, T2, T3, T4, T5]&gt;</i>
497
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/tuple.js 'Source')<br />
774
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/tuple.js 'Source')<br />
498
775
  <a name="tuple6" href="#tuple6">#</a> <b>tuple6</b><i>&lt;T1, T2, T3, T4, T5,
499
776
  T6&gt;</i>(<i>Decoder&lt;T1&gt;</i>, <i>Decoder&lt;T2&gt;</i>, <i>Decoder&lt;T3&gt;</i>,
500
777
  <i>Decoder&lt;T4&gt;</i>, <i>Decoder&lt;T5&gt;</i>, <i>Decoder&lt;T6&gt;</i>):
501
778
  <i>Decoder&lt;[T1, T2, T3, T4, T5, T6]&gt;</i>
502
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/tuple.js 'Source')
779
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/tuple.js 'Source')
503
780
 
504
- Returns a decoder capable of decoding **a 2-tuple of <i>(T1, T2)</i>'s**, provided that
505
- you already have a decoder for <i>T1</i> and <i>T2</i>. A tuple is like an Array, but the
506
- number of items in the array is fixed (two) and their types don't have to be homogeneous.
781
+ Accepts a _n_-tuple (an array with exactly _n_ items) of values accepted by the _n_ given
782
+ decoders.
507
783
 
784
+ <!-- prettier-ignore-start -->
508
785
  ```javascript
509
- const mydecoder = guard(tuple2(string, number));
510
- mydecoder(['hello', 1.2]) === ['hello', 1.2];
511
- mydecoder(['hello', 'world']); // DecodeError
786
+ const verify = guard(tuple2(string, number));
787
+
788
+ // 👍
789
+ verify(['hello', 1.2]) === ['hello', 1.2];
790
+
791
+ // 👎
792
+ verify([]); // throws, too few items
793
+ verify(['hello', 'world']); // throws, not the right types
794
+ verify(['a', 1, 'c']); // throws, too many items
512
795
  ```
796
+ <!-- prettier-ignore-end -->
513
797
 
514
798
  ---
515
799
 
516
800
  <a name="object" href="#object">#</a> <b>object</b><i>&lt;O: { [field: string]:
517
801
  Decoder&lt;any&gt; }&gt;</i>(mapping: O): <i>Decoder&lt;{ ... }&gt;</i>
518
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/object.js 'Source')
802
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/object.js 'Source')
519
803
 
520
- Returns a decoder capable of decoding **objects of the given shape** corresponding
521
- decoders, provided that you already have decoders for all values in the mapping.
804
+ Accepts object values with fields matching the given decoders. Extra fields that exist on
805
+ the input object are ignored and will not be returned.
522
806
 
807
+ <!-- prettier-ignore-start -->
523
808
  ```javascript
524
- const mydecoder = guard(
809
+ const verify = guard(
525
810
  object({
526
811
  x: number,
527
812
  y: number,
528
- })
813
+ }),
529
814
  );
530
- mydecoder({ x: 1, y: 2 }) === { x: 1, y: 2 };
531
- mydecoder({ x: 1, y: 2, z: 3 }) === { x: 1, y: 2 }; // ⚠️
532
- mydecoder({ x: 1 }); // DecodeError (Missing key: "y")
815
+
816
+ // 👍
817
+ verify({ x: 1, y: 2 }) === { x: 1, y: 2 };
818
+ verify({ x: 1, y: 2, z: 3 }) === { x: 1, y: 2 }; // ⚠️ extra field `z` not returned!
819
+
820
+ // 👎
821
+ verify({ x: 1 }); // throws, missing field `y`
533
822
  ```
823
+ <!-- prettier-ignore-end -->
534
824
 
535
825
  For more information, see also
536
826
  [The difference between `object`, `exact`, and `inexact`](#the-difference-between-object-exact-and-inexact).
@@ -539,21 +829,28 @@ For more information, see also
539
829
 
540
830
  <a name="exact" href="#exact">#</a> <b>exact</b><i>&lt;O: { [field: string]:
541
831
  Decoder&lt;any&gt; }&gt;</i>(mapping: O): <i>Decoder&lt;{ ... }&gt;</i>
542
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/object.js 'Source')
832
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/object.js 'Source')
543
833
 
544
- Like `object()`, but will fail if there are superfluous keys in the input data.
834
+ Like `object()`, but will reject inputs that contain extra keys that are not specified
835
+ explicitly.
545
836
 
837
+ <!-- prettier-ignore-start -->
546
838
  ```javascript
547
- const mydecoder = guard(
839
+ const verify = guard(
548
840
  exact({
549
841
  x: number,
550
842
  y: number,
551
- })
843
+ }),
552
844
  );
553
- mydecoder({ x: 1, y: 2 }) === { x: 1, y: 2 };
554
- mydecoder({ x: 1, y: 2, z: 3 }); // DecodeError (Superfluous keys: "z")
555
- mydecoder({ x: 1 }); // DecodeError (Missing key: "y")
845
+
846
+ // 👍
847
+ verify({ x: 1, y: 2 }) === { x: 1, y: 2 };
848
+
849
+ // 👎
850
+ verify({ x: 1, y: 2, z: 3 }); // throws, extra field `z` not allowed
851
+ verify({ x: 1 }); // throws, missing field `y`
556
852
  ```
853
+ <!-- prettier-ignore-end -->
557
854
 
558
855
  For more information, see also
559
856
  [The difference between `object`, `exact`, and `inexact`](#the-difference-between-object-exact-and-inexact).
@@ -562,88 +859,116 @@ For more information, see also
562
859
 
563
860
  <a name="inexact" href="#inexact">#</a> <b>inexact</b><i>&lt;O: { [field: string]:
564
861
  Decoder&lt;any&gt; }&gt;</i>(mapping: O): <i>Decoder&lt;{ ... }&gt;</i>
565
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/object.js 'Source')
862
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/object.js 'Source')
566
863
 
567
- Like `object()`, but will retain any extra properties on the input type unvalidated that
568
- are not part of the decoder definition.
864
+ Like `object()`, but will pass through any extra fields on the input object unvalidated
865
+ that will thus be of `unknown` type statically.
569
866
 
867
+ <!-- prettier-ignore-start -->
570
868
  ```javascript
571
- const mydecoder = guard(
869
+ const verify = guard(
572
870
  inexact({
573
871
  x: number,
574
- })
872
+ }),
575
873
  );
576
874
 
577
- mydecoder({ x: 1, y: 2 }) === { x: 1, y: 2 };
578
- mydecoder({ x: 1, y: 2, z: 3 }) === { x: 1, y: 2, z: 3 };
579
- mydecoder({ x: 1 }); // DecodeError (Missing key: "y")
875
+ // 👍
876
+ verify({ x: 1, y: 2 }) === { x: 1, y: 2 };
877
+ verify({ x: 1, y: 2, z: 3 }) === { x: 1, y: 2, z: 3 };
878
+
879
+ // 👎
880
+ verify({ x: 1 }); // throws, missing field `y`
580
881
  ```
882
+ <!-- prettier-ignore-end -->
581
883
 
582
884
  For more information, see also
583
885
  [The difference between `object`, `exact`, and `inexact`](#the-difference-between-object-exact-and-inexact).
584
886
 
585
887
  ---
586
888
 
587
- <a name="mapping" href="#mapping">#</a>
588
- <b>mapping</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>): <i>Decoder&lt;Map&lt;string,
589
- T&gt;&gt;</i>
590
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/mapping.js 'Source')
591
-
592
- Returns a decoder capable of decoding **Map instances of strings-to-T's** , provided that
593
- you already have a decoder for <i>T</i>.
889
+ <a name="pojo" href="#pojo">#</a> <b>pojo</b>: <i>Decoder&lt;{ [key: string]: unknown
890
+ }&gt;</i>
891
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/object.js 'Source')
594
892
 
595
- The main difference between `object()` and `mapping()` is that you'd typically use
596
- `object()` if this is a record-like object, where you know all the field names and the
597
- values are heterogeneous. Whereas with Mappings the keys are typically unknown and the
598
- values homogeneous.
893
+ Accepts any "plain old JavaScript object", but doesn't validate its keys or values
894
+ further.
599
895
 
896
+ <!-- prettier-ignore-start -->
600
897
  ```javascript
601
- const mydecoder = guard(mapping(person)); // Assume you have a "person" decoder already
602
- mydecoder({
603
- '1': { name: 'Alice' },
604
- '2': { name: 'Bob' },
605
- '3': { name: 'Charlie' },
606
- }) ===
607
- Map([
608
- ['1', { name: 'Alice' }],
609
- ['2', { name: 'Bob' }],
610
- ['3', { name: 'Charlie' }],
611
- ]);
898
+ const verify = guard(pojo);
899
+
900
+ // 👍
901
+ verify({}) === {};
902
+ verify({ name: 'hi' }) === { name: 'hi' };
903
+
904
+ // 👎
905
+ verify('hi'); // throws
906
+ verify([]); // throws
907
+ verify(new Date()); // throws
908
+ verify(null); // throws
612
909
  ```
910
+ <!-- prettier-ignore-end -->
613
911
 
614
912
  ---
615
913
 
616
914
  <a name="dict" href="#dict">#</a> <b>dict</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>):
617
915
  <i>Decoder&lt;{ [string]: &lt;T&gt;}&gt;</i>
618
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/mapping.js 'Source')
916
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/mapping.js 'Source')
619
917
 
620
- Like `mapping()`, but returns an object instead of a `Map` instance.
918
+ Accepts objects where all values match the given decoder, and returns the result as a
919
+ `{ [string]: T }`.
920
+
921
+ The main difference between `object()` and `dict()` is that you'd typically use `object()`
922
+ if this is a record-like object, where all field names are known and the values are
923
+ heterogeneous. Whereas with `dict()` the keys are typically dynamic and the values
924
+ homogeneous, like in a dictionary, a lookup table, or a cache.
621
925
 
622
926
  ```javascript
623
- const mydecoder = guard(dict(person)); // Assume you have a "person" decoder already
624
- mydecoder({
625
- '1': { name: 'Alice' },
626
- '2': { name: 'Bob' },
627
- '3': { name: 'Charlie' },
628
- });
927
+ const verify = guard(dict(person)); // Assume you have a "person" decoder already
928
+
929
+ // 👍
930
+ verify({
931
+ 1: { name: 'Alice' },
932
+ 2: { name: 'Bob' },
933
+ 3: { name: 'Charlie' },
934
+ }); // ≈ {
935
+ // "1": { name: "Alice" },
936
+ // "2": { name: "Bob" },
937
+ // "3": { name: "Charlie" },
938
+ // }
629
939
  ```
630
940
 
631
- Would equal:
941
+ ---
942
+
943
+ <a name="mapping" href="#mapping">#</a>
944
+ <b>mapping</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>): <i>Decoder&lt;Map&lt;string,
945
+ T&gt;&gt;</i>
946
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/mapping.js 'Source')
947
+
948
+ Like `dict()`, but returns the result as a `Map<string, T>` instead.
632
949
 
633
950
  ```javascript
634
- {
635
- "1": { name: "Alice" },
636
- "2": { name: "Bob" },
637
- "3": { name: "Charlie" },
638
- }
951
+ const verify = guard(mapping(person)); // Assume you have a "person" decoder already
952
+
953
+ // 👍
954
+ verify({
955
+ 1: { name: 'Alice' },
956
+ 2: { name: 'Bob' },
957
+ 3: { name: 'Charlie' },
958
+ });
959
+ // ≈ Map([
960
+ // ['1', { name: 'Alice' }],
961
+ // ['2', { name: 'Bob' }],
962
+ // ['3', { name: 'Charlie' }],
963
+ // ]);
639
964
  ```
640
965
 
641
966
  ---
642
967
 
643
968
  <a name="json" href="#json">#</a> <b>json</b>: <i>Decoder&lt;JSONValue&gt;</i>
644
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/json.js 'Source')
969
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/json.js 'Source')
645
970
 
646
- Returns a decoder capable of decoding **any valid JSON value**:
971
+ Accepts any value that's a valid JSON value:
647
972
 
648
973
  - `null`
649
974
  - `string`
@@ -653,8 +978,10 @@ Returns a decoder capable of decoding **any valid JSON value**:
653
978
  - `Array<JSONValue>`
654
979
 
655
980
  ```javascript
656
- const mydecoder = guard(json);
657
- mydecoder({
981
+ const verify = guard(json);
982
+
983
+ // 👍
984
+ verify({
658
985
  name: 'Amir',
659
986
  age: 27,
660
987
  admin: true,
@@ -669,74 +996,90 @@ Any value returned by `JSON.parse()` should decode without failure.
669
996
 
670
997
  <a name="jsonObject" href="#jsonObject">#</a> <b>jsonObject</b>:
671
998
  <i>Decoder&lt;JSONObject&gt;</i>
672
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/json.js 'Source')
999
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/json.js 'Source')
673
1000
 
674
1001
  Like `json`, but will only decode when the JSON value is an object.
675
1002
 
1003
+ <!-- prettier-ignore-start -->
676
1004
  ```javascript
677
- const mydecoder = guard(json);
678
- mydecoder({}); // OK
679
- mydecoder({ name: 'Amir' }); // OK
1005
+ const verify = guard(json);
1006
+
1007
+ // 👍
1008
+ verify({}); // ≈ {}
1009
+ verify({ name: 'Amir' }); // ≈ { name: 'Amir' }
680
1010
 
681
- // Error: the following values are valid JSON values, but not Objects
682
- mydecoder([]); // Error
683
- mydecoder([{ name: 'Alice' }, { name: 'Bob' }]); // Error
684
- mydecoder('hello'); // Error
685
- mydecoder(null); // Error
1011
+ // 👎
1012
+ verify([]); // throws
1013
+ verify([{ name: 'Alice' }]); // throws
1014
+ verify('hello'); // throws
1015
+ verify(null); // throws
686
1016
  ```
1017
+ <!-- prettier-ignore-end -->
687
1018
 
688
1019
  ---
689
1020
 
690
1021
  <a name="jsonArray" href="#jsonArray">#</a> <b>jsonArray</b>:
691
1022
  <i>Decoder&lt;JSONArray&gt;</i>
692
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/json.js 'Source')
1023
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/json.js 'Source')
693
1024
 
694
1025
  Like `json`, but will only decode when the JSON value is an array.
695
1026
 
1027
+ <!-- prettier-ignore-start -->
696
1028
  ```javascript
697
- const mydecoder = guard(json);
698
- mydecoder([]); // OK
699
- mydecoder([{ name: 'Amir' }]); // OK
1029
+ const verify = guard(json);
700
1030
 
701
- // Error: the following values are valid JSON values, but not Objects
702
- mydecoder({}); // Error
703
- mydecoder({ name: 'Alice' }); // Error
704
- mydecoder('hello'); // Error
705
- mydecoder(null); // Error
1031
+ // 👍
1032
+ verify([]); // ≈ []
1033
+ verify([{ name: 'Amir' }]); // ≈ [{ name: 'Amir' }]
1034
+
1035
+ // 👎
1036
+ verify({}); // throws
1037
+ verify({ name: 'Alice' }); // throws
1038
+ verify('hello'); // throws
1039
+ verify(null); // throws
706
1040
  ```
1041
+ <!-- prettier-ignore-end -->
707
1042
 
708
1043
  ---
709
1044
 
710
1045
  <a name="either" href="#either">#</a> <b>either</b><i>&lt;T1,
711
1046
  T2&gt;</i>(<i>Decoder&lt;T1&gt;</i>, <i>Decoder&lt;T2&gt;</i>): <i>Decoder&lt;T1 |
712
1047
  T2&gt;</i><br />
713
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/either.js 'Source')<br />
1048
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/either.js 'Source')<br />
714
1049
  <a name="either2" href="#either2">#</a> <b>either2</b><i>&lt;T1,
715
1050
  T2&gt;</i>(<i>Decoder&lt;T1&gt;</i>, <i>Decoder&lt;T2&gt;</i>): <i>Decoder&lt;T1 |
716
1051
  T2&gt;</i><br />
717
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/either.js 'Source')<br />
1052
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/either.js 'Source')<br />
718
1053
  <a name="either3" href="#either3">#</a> <b>either3</b><i>&lt;T1, T2,
719
1054
  T3&gt;</i>(<i>Decoder&lt;T1&gt;</i>, <i>Decoder&lt;T2&gt;</i>, <i>Decoder&lt;T3&gt;</i>):
720
1055
  <i>Decoder&lt;T1 | T2 | T3&gt;</i>
721
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/either.js 'Source')<br /> ...
1056
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/either.js 'Source')<br />
1057
+ ...
722
1058
 
723
- Returns a decoder capable of decoding **either one of <i>T1</i> or <i>T2</i>**, provided
724
- that you already have decoders for <i>T1</i> and <i>T2</i>. Eithers exist for arities up
725
- until 9 (either, either3, either4, ..., either9).
1059
+ Accepts any value that is accepted by any of the given decoders. Eithers exist for arities
1060
+ up until 9 (`either`, `either3`, `either4`, ..., `either9`).
726
1061
 
1062
+ <!-- prettier-ignore-start -->
727
1063
  ```javascript
728
- const mydecoder = guard(either(number, string));
729
- mydecoder('hello world') === 'hello world';
730
- mydecoder(123) === 123;
731
- mydecoder(false); // DecodeError
1064
+ const verify = guard(either(number, string));
1065
+
1066
+ // 👍
1067
+ verify('hello world') === 'hello world';
1068
+ verify(123) === 123;
1069
+
1070
+ // 👎
1071
+ verify(false); // throws
732
1072
  ```
1073
+ <!-- prettier-ignore-end -->
733
1074
 
734
1075
  ---
735
1076
 
736
- <a name="dispatch" href="#dispatch">#</a> <b>dispatch</b><i>&lt;O: { [field: string]:
737
- (Decoder&lt;T&gt; | Decoder&lt;V&gt; | ...) }&gt;</i>(field: string, mapping: O):
738
- <i>Decoder&lt;T | V | ...&gt;</i>
739
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/dispatch.js 'Source')
1077
+ <a name="disjointUnion" href="#disjointUnion">#</a> <b>disjointUnion</b><i>&lt;O: {
1078
+ [field: string]: (Decoder&lt;T&gt; | Decoder&lt;V&gt; | ...) }&gt;</i>(field: string,
1079
+ mapping: O): <i>Decoder&lt;T | V | ...&gt;</i>
1080
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/dispatch.js 'Source')
1081
+
1082
+ **NOTE:** In decoders@1.x, this was called `dispatch()`.
740
1083
 
741
1084
  Like the `either` family, but only for building unions of object types with a common field
742
1085
  (like a `type` field) that lets you distinguish members.
@@ -744,19 +1087,19 @@ Like the `either` family, but only for building unions of object types with a co
744
1087
  The following two decoders are effectively equivalent:
745
1088
 
746
1089
  ```javascript
747
- type Rect = {| __type: 'rect', x: number, y: number, width: number, height: number |};
748
- type Circle = {| __type: 'circle', cx: number, cy: number, r: number |};
749
- // ^^^^^^
750
- // Field that defines which decoder to pick
1090
+ type Rect = { __type: 'rect', x: number, y: number, width: number, height: number };
1091
+ type Circle = { __type: 'circle', cx: number, cy: number, r: number };
1092
+ // ^^^^^^
1093
+ // Field that defines which decoder to pick
751
1094
  // vvvvvv
752
- const shape1: Decoder<Rect | Circle> = dispatch('__type', { rect, circle });
1095
+ const shape1: Decoder<Rect | Circle> = disjointUnion('__type', { rect, circle });
753
1096
  const shape2: Decoder<Rect | Circle> = either(rect, circle);
754
1097
  ```
755
1098
 
756
- But using `dispatch()` will typically be more runtime-efficient than using `either()`. The
757
- reason is that `dispatch()` will first do minimal work to "look ahead" into the `type`
758
- field here, and based on that value, pick which decoder to invoke. Error messages will
759
- then also be tailored to the specific decoder.
1099
+ But using `disjointUnion()` will typically be more runtime-efficient than using
1100
+ `either()`. The reason is that `disjointUnion()` will first do minimal work to "look
1101
+ ahead" into the `type` field here, and based on that value, pick which decoder to invoke.
1102
+ Error messages will then also be tailored to the specific decoder.
760
1103
 
761
1104
  The `either()` version will instead try each decoder in turn until it finds one that
762
1105
  matches. If none of the alternatives match, it needs to report all errors, which is
@@ -766,19 +1109,24 @@ sometimes confusing.
766
1109
 
767
1110
  <a name="oneOf" href="#oneOf">#</a> <b>oneOf</b><i>&lt;T&gt;</i>(<i>Array&lt;T&gt;</i>):
768
1111
  <i>Decoder&lt;T&gt;</i>
769
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/either.js 'Source')<br />
1112
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/either.js 'Source')<br />
770
1113
 
771
- Returns a decoder capable of decoding values that are equal (using `===`) to any of the
772
- given constants. The returned value will always be one of the given constants at runtime.
1114
+ Accepts any value that is strictly-equal (using `===`) to one of the specified values.
773
1115
 
1116
+ <!-- prettier-ignore-start -->
774
1117
  ```javascript
775
- const mydecoder = guard(oneOf(['foo', 'bar', 3]));
776
- mydecoder('foo') === 'foo';
777
- mydecoder(3) === 3;
778
- mydecoder('hello'); // DecodeError
779
- mydecoder(4); // DecodeError
780
- mydecoder(false); // DecodeError
1118
+ const verify = guard(oneOf(['foo', 'bar', 3]));
1119
+
1120
+ // 👍
1121
+ verify('foo') === 'foo';
1122
+ verify(3) === 3;
1123
+
1124
+ // 👎
1125
+ verify('hello'); // throws
1126
+ verify(4); // throws
1127
+ verify(false); // throws
781
1128
  ```
1129
+ <!-- prettier-ignore-end -->
782
1130
 
783
1131
  For example, given an array of strings, like so:
784
1132
 
@@ -795,72 +1143,109 @@ annotate the type. Either by doing `oneOf([('foo': 'foo'), ('bar': 'bar')])`, or
795
1143
 
796
1144
  <a name="instanceOf" href="#instanceOf">#</a>
797
1145
  <b>instanceOf</b><i>&lt;T&gt;</i>(<i>Class&lt;T&gt;</i>): <i>Decoder&lt;T&gt;</i>
798
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/instanceOf.js 'Source')<br />
1146
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/instanceOf.js 'Source')<br />
799
1147
 
800
- Returns a decoder capable of decoding values that are instances of the given class.
1148
+ Accepts any value that is an `instanceof` the given class.
801
1149
 
802
1150
  > **NOTE: Help wanted!** The TypeScript annotation for this decoder needs help! If you
803
1151
  > know how to express it, please submit a PR. See
804
- > https://github.com/nvie/decoders/blob/master/src/instanceOf.d.ts
1152
+ > https://github.com/nvie/decoders/blob/main/src/core/instanceOf.d.ts
805
1153
 
1154
+ <!-- prettier-ignore-start -->
806
1155
  ```javascript
807
- const mydecoder = guard(instanceOf(Error));
1156
+ const verify = guard(instanceOf(Error));
1157
+
1158
+ // 👍
808
1159
  const value = new Error('foo');
809
- mydecoder(value) === value;
810
- mydecoder('foo'); // DecodeError
811
- mydecoder(3); // DecodeError
1160
+ verify(value) === value;
1161
+
1162
+ // 👎
1163
+ verify('foo'); // throws
1164
+ verify(3); // throws
812
1165
  ```
1166
+ <!-- prettier-ignore-end -->
813
1167
 
814
1168
  ---
815
1169
 
816
1170
  <a name="map" href="#map">#</a> <b>map</b><i>&lt;T, V&gt;</i>(<i>Decoder&lt;T&gt;</i>,
817
1171
  <i>&lt;T&gt;</i> =&gt; <i>&lt;V&gt;</i>): <i>Decoder&lt;V&gt;</i>
818
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/utils.js 'Source')<br />
1172
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/utils.js 'Source')<br />
819
1173
 
820
- Given a decoder and a mapper function, will first decode the value using the given
821
- decoder, and on success, will call the mapper function **on the decoded value**. If the
822
- mapper function throws an error, the whole decoder will fail using the error message as
823
- the failure reason.
1174
+ Accepts any value the given decoder accepts, and on success, will call the mapper value
1175
+ **on the decoded result**. If the mapper function throws an error, the whole decoder will
1176
+ fail using the error message as the failure reason.
824
1177
 
1178
+ <!-- prettier-ignore-start -->
825
1179
  ```javascript
826
1180
  const upper = map(string, (s) => s.toUpperCase());
1181
+ const verify = guard(upper);
1182
+
1183
+ // 👍
1184
+ verify('foo') === 'FOO';
827
1185
 
828
- const mydecoder = guard(upper);
829
- mydecoder(4); // DecodeError
830
- mydecoder('foo') === 'FOO';
1186
+ // 👎
1187
+ verify(4); // throws
831
1188
  ```
1189
+ <!-- prettier-ignore-end -->
832
1190
 
833
1191
  ---
834
1192
 
835
1193
  <a name="compose" href="#compose">#</a> <b>compose</b><i>&lt;T,
836
1194
  V&gt;</i>(<i>Decoder&lt;T&gt;</i>, <i>Decoder&lt;V, T&gt;</i>): <i>Decoder&lt;V&gt;</i>
837
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/utils.js 'Source')<br />
1195
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/composition.js 'Source')<br />
1196
+
1197
+ Given a decoder for _T_ and another one for _V_-given-a-_T_. Will first decode the input
1198
+ using the first decoder, and _if okay_, pass the result on to the second decoder. The
1199
+ second decoder will thus be able to make more assumptions about its input value, i.e. it
1200
+ can know what type the input value is (`T` instead of `unknown`).
1201
+
1202
+ This is an advanced decoder, typically only useful for authors of decoders. It's not
1203
+ recommended to rely on this decoder directly for normal usage.
1204
+
1205
+ ---
1206
+
1207
+ <a name="predicate" href="#predicate">#</a>
1208
+ <b>predicate</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>, <i>&lt;T&gt; => boolean</i>,
1209
+ string): <i>Decoder&lt;T&gt;</i>
1210
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/predicate.js 'Source')<br />
1211
+
1212
+ Accepts values that are accepted by the decoder _and_ also pass the predicate function.
838
1213
 
839
- Given a decoder for _T_ and another one for _V_, will first decode using _T_, and then
840
- call the _V_ decoder **on the original value**. This differs from `map()` in that it was
841
- access to the original value, but may assume the type value is already refined by the
842
- first decoder.
1214
+ <!-- prettier-ignore-start -->
1215
+ ```typescript
1216
+ const odd = predicate(
1217
+ number,
1218
+ (n) => n % 2 === 1,
1219
+ 'Must be odd'
1220
+ );
1221
+ const verify = guard(odd);
1222
+
1223
+ // 👍
1224
+ verify(3) === 3;
1225
+
1226
+ // 👎
1227
+ verify('hi'); // throws: not a number
1228
+ verify(42); // throws: not an odd number
1229
+ ```
1230
+ <!-- prettier-ignore-end -->
843
1231
 
844
- Although the `compose()` function is essentially more low-level and powerful then the
845
- `map()` function, it's mostly useful in combination with the `predicate()` helper
846
- function, which allows you to rely on an existing decoder, but add extra checks on the
847
- specific values that will be allowed at runtime.
1232
+ In TypeScript, if you provide a predicate that also doubles as a [type
1233
+ predicate][type-predicates], then this will be reflected in the return type, too.
848
1234
 
849
1235
  ---
850
1236
 
851
1237
  <a name="describe" href="#describe">#</a>
852
1238
  <b>describe</b><i>&lt;T&gt;</i>(<i>Decoder&lt;T&gt;</i>, <i>string</i>):
853
1239
  <i>Decoder&lt;T&gt;</i>
854
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/describe.js 'Source')<br />
1240
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/describe.js 'Source')<br />
855
1241
 
856
- Defers to the given decoder, but when a decoding error happens, replace the error message
857
- with the given one. This can be used to simplify or shorten otherwise long or
858
- low-level/technical errors.
1242
+ Uses the given decoder, but will use an alternative error message in case it rejects. This
1243
+ can be used to simplify or shorten otherwise long or low-level/technical errors.
859
1244
 
860
1245
  ```javascript
861
1246
  const vowel = describe(
862
1247
  either5(constant('a'), constant('e'), constant('i'), constant('o'), constant('u')),
863
- 'Must be vowel'
1248
+ 'Must be vowel',
864
1249
  );
865
1250
  ```
866
1251
 
@@ -868,7 +1253,7 @@ const vowel = describe(
868
1253
 
869
1254
  <a name="lazy" href="#lazy">#</a> <b>lazy</b><i>&lt;T&gt;</i>(() =>
870
1255
  <i>Decoder&lt;T&gt;</i>): <i>Decoder&lt;T&gt;</i>
871
- [&lt;&gt;](https://github.com/nvie/decoders/blob/master/src/lazy.js 'Source')<br />
1256
+ [&lt;&gt;](https://github.com/nvie/decoders/blob/main/src/core/lazy.js 'Source')<br />
872
1257
 
873
1258
  Lazily evaluate the given decoder. This is useful to build self-referential types for
874
1259
  recursive data structures. Example:
@@ -916,11 +1301,11 @@ And a runtime input of:
916
1301
  }
917
1302
  ```
918
1303
 
919
- | | Extra properties | Output value | Inferred type |
920
- | ---------------- | ---------------- | ------------------------------ | ----------------------------------------- |
921
- | `object(thing)` | discarded | `{a: "hi", b: 42}` | `{a: string, b: number}` |
922
- | `exact(thing)` | not allowed | ⚡️ Runtime error | `{a: string, b: number}` |
923
- | `inexact(thing)` | retained | `{a: "hi", b: 42, c: "extra"}` | `{a: string, b: number, [string]: mixed}` |
1304
+ | | Extra properties | Output value | Inferred type |
1305
+ | ---------------- | ---------------- | ------------------------------ | ------------------------------------------- |
1306
+ | `object(thing)` | discarded | `{a: "hi", b: 42}` | `{a: string, b: number}` |
1307
+ | `exact(thing)` | not allowed | ⚡️ Runtime error | `{a: string, b: number}` |
1308
+ | `inexact(thing)` | retained | `{a: "hi", b: 42, c: "extra"}` | `{a: string, b: number, [string]: unknown}` |
924
1309
 
925
1310
  ### Building custom decoders
926
1311
 
@@ -944,7 +1329,7 @@ const numericString: Decoder<number> = map(
944
1329
  // At runtime, expect to read a string...
945
1330
  string,
946
1331
  // ...but return it as a number
947
- (s) => Number(s)
1332
+ (s) => Number(s),
948
1333
  );
949
1334
  ```
950
1335
 
@@ -962,15 +1347,15 @@ business logic outside decoders makes them more reusable and composable.
962
1347
  #### Adding predicates
963
1348
 
964
1349
  The easiest way to decode using an existing decoder, but enforcing extra runtime checks on
965
- their values is by using the `compose(..., predicate(...))` construction:
1350
+ their values is by wrapping it in a `predicate(...)` construction:
966
1351
 
967
1352
  ```js
968
- const odd = compose(
969
- integer,
970
- predicate((n) => n % 2 !== 0, 'Must be odd')
971
- );
972
- const shortString = compose(
973
- string,
974
- predicate((s) => s.length < 8, 'Must be less than 8 chars')
975
- );
1353
+ const odd = predicate(integer, (n) => n % 2 !== 0, 'Must be odd');
1354
+ const shortString = predicate(string, (s) => s.length < 8, 'Must be less than 8 chars');
976
1355
  ```
1356
+
1357
+ [date-api]:
1358
+ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
1359
+ [iso8601-fmt]: https://en.wikipedia.org/wiki/ISO_8601
1360
+ [type-predicates]:
1361
+ https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates