@fgv/ts-utils 4.1.0 → 4.2.0

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 (67) hide show
  1. package/CHANGELOG.json +18 -0
  2. package/CHANGELOG.md +10 -1
  3. package/dist/ts-utils.d.ts +553 -54
  4. package/lib/index.d.ts +3 -1
  5. package/lib/index.d.ts.map +1 -1
  6. package/lib/index.js +6 -1
  7. package/lib/index.js.map +1 -1
  8. package/lib/packlets/collections/common.d.ts +6 -0
  9. package/lib/packlets/collections/common.d.ts.map +1 -0
  10. package/lib/packlets/collections/common.js +24 -0
  11. package/lib/packlets/collections/common.js.map +1 -0
  12. package/lib/packlets/collections/index.d.ts +8 -0
  13. package/lib/packlets/collections/index.d.ts.map +1 -0
  14. package/lib/packlets/collections/index.js +68 -0
  15. package/lib/packlets/collections/index.js.map +1 -0
  16. package/lib/packlets/collections/readonlyResultMap.d.ts +58 -0
  17. package/lib/packlets/collections/readonlyResultMap.d.ts.map +1 -0
  18. package/lib/packlets/collections/readonlyResultMap.js +24 -0
  19. package/lib/packlets/collections/readonlyResultMap.js.map +1 -0
  20. package/lib/packlets/collections/resultMap.d.ts +155 -0
  21. package/lib/packlets/collections/resultMap.d.ts.map +1 -0
  22. package/lib/packlets/collections/resultMap.js +216 -0
  23. package/lib/packlets/collections/resultMap.js.map +1 -0
  24. package/lib/packlets/collections/resultMapValidator.d.ts +82 -0
  25. package/lib/packlets/collections/resultMapValidator.d.ts.map +1 -0
  26. package/lib/packlets/collections/resultMapValidator.js +104 -0
  27. package/lib/packlets/collections/resultMapValidator.js.map +1 -0
  28. package/lib/packlets/collections/utils.d.ts +69 -0
  29. package/lib/packlets/collections/utils.d.ts.map +1 -0
  30. package/lib/packlets/collections/utils.js +116 -0
  31. package/lib/packlets/collections/utils.js.map +1 -0
  32. package/lib/packlets/collections/validatingResultMap.d.ts +66 -0
  33. package/lib/packlets/collections/validatingResultMap.d.ts.map +1 -0
  34. package/lib/packlets/collections/validatingResultMap.js +93 -0
  35. package/lib/packlets/collections/validatingResultMap.js.map +1 -0
  36. package/lib/packlets/conversion/baseConverter.d.ts +7 -3
  37. package/lib/packlets/conversion/baseConverter.d.ts.map +1 -1
  38. package/lib/packlets/conversion/baseConverter.js +10 -0
  39. package/lib/packlets/conversion/baseConverter.js.map +1 -1
  40. package/lib/packlets/conversion/converter.d.ts +19 -3
  41. package/lib/packlets/conversion/converter.d.ts.map +1 -1
  42. package/lib/packlets/conversion/converter.js.map +1 -1
  43. package/lib/packlets/conversion/converters.d.ts +42 -42
  44. package/lib/packlets/conversion/converters.d.ts.map +1 -1
  45. package/lib/packlets/conversion/converters.js +9 -9
  46. package/lib/packlets/conversion/converters.js.map +1 -1
  47. package/lib/packlets/conversion/defaultingConverter.d.ts +6 -2
  48. package/lib/packlets/conversion/defaultingConverter.d.ts.map +1 -1
  49. package/lib/packlets/conversion/defaultingConverter.js +7 -0
  50. package/lib/packlets/conversion/defaultingConverter.js.map +1 -1
  51. package/lib/packlets/conversion/objectConverter.d.ts +3 -3
  52. package/lib/packlets/conversion/objectConverter.d.ts.map +1 -1
  53. package/lib/packlets/conversion/objectConverter.js.map +1 -1
  54. package/lib/packlets/validation/field.d.ts +1 -1
  55. package/lib/packlets/validation/field.d.ts.map +1 -1
  56. package/lib/packlets/validation/field.js.map +1 -1
  57. package/lib/packlets/validation/genericValidator.d.ts +6 -2
  58. package/lib/packlets/validation/genericValidator.d.ts.map +1 -1
  59. package/lib/packlets/validation/genericValidator.js +19 -2
  60. package/lib/packlets/validation/genericValidator.js.map +1 -1
  61. package/lib/packlets/validation/validator.d.ts +18 -1
  62. package/lib/packlets/validation/validator.d.ts.map +1 -1
  63. package/lib/packlets/validation/validator.js.map +1 -1
  64. package/lib/packlets/validation/validatorBase.d.ts +1 -1
  65. package/lib/packlets/validation/validatorBase.d.ts.map +1 -1
  66. package/lib/packlets/validation/validatorBase.js.map +1 -1
  67. package/package.json +1 -1
@@ -22,7 +22,7 @@ export declare function allSucceed<T>(results: Iterable<Result<unknown>>, succes
22
22
  * @returns A {@link Converter | Converter} which returns an array of `<T>`.
23
23
  * @public
24
24
  */
25
- declare function arrayOf<T, TC = undefined>(converter: Converter<T, TC> | Validator<T, TC>, onError?: OnError): Converter<T[], TC>;
25
+ declare function arrayOf<T, TC = unknown>(converter: Converter<T, TC> | Validator<T, TC>, onError?: OnError): Converter<T[], TC>;
26
26
 
27
27
  /**
28
28
  * Helper function to create a {@link Validation.Classes.ArrayValidator | ArrayValidator} which
@@ -84,7 +84,7 @@ declare namespace Base {
84
84
  * Base templated wrapper to simplify creation of new {@link Converter}s.
85
85
  * @public
86
86
  */
87
- declare class BaseConverter<T, TC = undefined> implements Converter<T, TC> {
87
+ declare class BaseConverter<T, TC = unknown> implements Converter<T, TC> {
88
88
  /**
89
89
  * @internal
90
90
  */
@@ -170,6 +170,10 @@ declare class BaseConverter<T, TC = undefined> implements Converter<T, TC> {
170
170
  * @internal
171
171
  */
172
172
  protected _context(supplied?: TC): TC | undefined;
173
+ /**
174
+ * {@inheritdoc Converter.withFormattedError}
175
+ */
176
+ withFormattedError(formatter: ConversionErrorFormatter<TC>): Converter<T, TC>;
173
177
  /**
174
178
  * @internal
175
179
  */
@@ -187,7 +191,7 @@ declare class BaseConverter<T, TC = undefined> implements Converter<T, TC> {
187
191
  * Anything else fails.
188
192
  * @public
189
193
  */
190
- declare const boolean: Converter<boolean, undefined>;
194
+ declare const boolean: Converter<boolean, unknown>;
191
195
 
192
196
  /**
193
197
  * A {@link Validation.Classes.BooleanValidator | BooleanValidator} which validates a boolean in place.
@@ -261,6 +265,25 @@ declare namespace Classes {
261
265
  }
262
266
  }
263
267
 
268
+ declare namespace Collections {
269
+ export {
270
+ Utils,
271
+ KeyValueEntry,
272
+ ResultMapResultDetail,
273
+ ResultMapForEachCb,
274
+ IReadOnlyResultMap,
275
+ IResultMapConstructorParams,
276
+ ResultMap,
277
+ IReadOnlyResultMapValidator,
278
+ IResultMapValidatorCreateParams,
279
+ ResultMapValidator,
280
+ IReadOnlyValidatingResultMap,
281
+ IValidatingResultMapConstructorParams,
282
+ ValidatingResultMap
283
+ }
284
+ }
285
+ export { Collections }
286
+
264
287
  /**
265
288
  * A {@link Validation.Constraint | Constraint<T>} function returns
266
289
  * `true` if the supplied value meets the constraint. Can return
@@ -296,6 +319,7 @@ declare namespace Conversion {
296
319
  BaseConverter,
297
320
  OnError,
298
321
  ConverterTraits,
322
+ ConversionErrorFormatter,
299
323
  ConstraintOptions,
300
324
  Converter,
301
325
  DefaultingConverter,
@@ -309,6 +333,16 @@ declare namespace Conversion {
309
333
  }
310
334
  export { Conversion }
311
335
 
336
+ /**
337
+ * Formats an incoming error message and value that failed validation.
338
+ * @param val - The value that failed validation.
339
+ * @param message - The default error message, if any.
340
+ * @param context - Optional validation context.
341
+ * @returns The formatted error message.
342
+ * @public
343
+ */
344
+ declare type ConversionErrorFormatter<TC = unknown> = (val: unknown, message?: string, context?: TC) => string;
345
+
312
346
  /**
313
347
  * Deprecated name for Infer<T> retained for compatibility
314
348
  * @deprecated use @see Infer instead
@@ -322,7 +356,7 @@ declare type ConvertedToType<TCONV> = Infer<TCONV>;
322
356
  * of optional templated type `<TC>` (default `undefined`).
323
357
  * @public
324
358
  */
325
- export declare interface Converter<T, TC = undefined> extends ConverterTraits {
359
+ export declare interface Converter<T, TC = unknown> extends ConverterTraits {
326
360
  /**
327
361
  * Indicates whether this element is explicitly optional.
328
362
  */
@@ -390,7 +424,7 @@ export declare interface Converter<T, TC = undefined> extends ConverterTraits {
390
424
  * converted result from this {@link Converter}.
391
425
  * @returns A new {@link Converter} returning `<T2>`.
392
426
  */
393
- mapConvert<T2>(mapConverter: Converter<T2>): Converter<T2, TC>;
427
+ mapConvert<T2>(mapConverter: Converter<T2, unknown>): Converter<T2, TC>;
394
428
  /**
395
429
  * Creates a {@link Converter} which maps the individual items of a collection
396
430
  * resulting from this {@link Converter} using the supplied map function.
@@ -454,6 +488,13 @@ export declare interface Converter<T, TC = undefined> extends ConverterTraits {
454
488
  * @returns A new {@link Converter} returning `<T>`.
455
489
  */
456
490
  withConstraint(constraint: (val: T) => boolean | Result<T>, options?: ConstraintOptions): Converter<T, TC>;
491
+ /**
492
+ * Creates a new {@link Converter} which is derived from this one but which returns an
493
+ * error message formatted by the supplied formatter if the conversion fails.
494
+ * @param formatter - The formatter to be applied.
495
+ * @returns A new {@link Converter} returning `<T>`.
496
+ */
497
+ withFormattedError(formatter: ConversionErrorFormatter<TC>): Converter<T, TC>;
457
498
  /**
458
499
  * returns a converter which adds a brand to the type to prevent mismatched usage
459
500
  * of simple types.
@@ -530,7 +571,7 @@ declare class Crc32Normalizer extends HashingNormalizer {
530
571
  /**
531
572
  * @public
532
573
  */
533
- declare interface DefaultingConverter<T, TD = T, TC = undefined> extends Converter<T | TD, TC> {
574
+ declare interface DefaultingConverter<T, TD = T, TC = unknown> extends Converter<T | TD, TC> {
534
575
  /**
535
576
  * Default value to use if the conversion fails.
536
577
  */
@@ -719,10 +760,10 @@ declare type DiscriminatedObjectConverters<T, TD extends string = string, TC = u
719
760
  * in the supplied array and can be converted. Returns {@link Failure | Failure} with an error message otherwise.
720
761
  * @param index - The index of the element to be extracted.
721
762
  * @param converter - A {@link Converter | Converter} or {@link Validator | Validator} for the extracted element.
722
- * @returns A {@link Converter | Converter<T>} which extracts the specified element from an array.
763
+ * @returns A {@link Converter | Converter<T, TC>} which extracts the specified element from an array.
723
764
  * @public
724
765
  */
725
- declare function element<T, TC = undefined>(index: number, converter: Converter<T, TC> | Validator<T, TC>): Converter<T, TC>;
766
+ declare function element<T, TC = unknown>(index: number, converter: Converter<T, TC> | Validator<T, TC>): Converter<T, TC>;
726
767
 
727
768
  /**
728
769
  * @internal
@@ -866,7 +907,7 @@ export declare function failWithDetail<T, TD>(message: string, detail: TD): Deta
866
907
  * field.
867
908
  * @public
868
909
  */
869
- declare function field<T, TC = undefined>(name: string, converter: Converter<T, TC> | Validator<T, TC>): Converter<T, TC>;
910
+ declare function field<T, TC = unknown>(name: string, converter: Converter<T, TC> | Validator<T, TC>): Converter<T, TC>;
870
911
 
871
912
  /**
872
913
  * Per-property converters or validators for each of the properties in type T.
@@ -933,7 +974,7 @@ declare interface FunctionConstraintTrait {
933
974
  * to substitute a supplied default value for any errors returned by the inner converter.
934
975
  * @public
935
976
  */
936
- declare class GenericDefaultingConverter<T, TD = T, TC = undefined> implements DefaultingConverter<T, TD, TC> {
977
+ declare class GenericDefaultingConverter<T, TD = T, TC = unknown> implements DefaultingConverter<T, TD, TC> {
937
978
  private _converter;
938
979
  /**
939
980
  * {@inheritdoc Conversion.DefaultingConverter.defaultValue}
@@ -1001,6 +1042,10 @@ declare class GenericDefaultingConverter<T, TD = T, TC = undefined> implements D
1001
1042
  * {@inheritdoc Converter.withBrand}
1002
1043
  */
1003
1044
  withBrand<B extends string>(brand: B): Converter<Brand<T | TD, B>, TC>;
1045
+ /**
1046
+ * {@inheritdoc Converter.withFormattedError}
1047
+ */
1048
+ withFormattedError(formatter: ConversionErrorFormatter<TC>): Converter<T | TD, TC>;
1004
1049
  /**
1005
1050
  * Returns a Converter which always succeeds with the supplied default value rather
1006
1051
  * than failing.
@@ -1016,7 +1061,7 @@ declare class GenericDefaultingConverter<T, TD = T, TC = undefined> implements D
1016
1061
  * Generic base implementation for an in-place {@link Validation.Validator | Validator}.
1017
1062
  * @public
1018
1063
  */
1019
- declare class GenericValidator<T, TC = undefined> implements Validator<T, TC> {
1064
+ declare class GenericValidator<T, TC = unknown> implements Validator<T, TC> {
1020
1065
  /**
1021
1066
  * {@inheritdoc Validation.Validator.traits}
1022
1067
  */
@@ -1071,6 +1116,10 @@ declare class GenericValidator<T, TC = undefined> implements Validator<T, TC> {
1071
1116
  * {@inheritdoc Validation.Validator.brand}
1072
1117
  */
1073
1118
  withBrand<B extends string>(brand: B): Validator<Brand<T, B>, TC>;
1119
+ /**
1120
+ * {@inheritdoc Validation.Validator.withFormattedError}
1121
+ */
1122
+ withFormattedError(formatter: ValidationErrorFormatter<TC>): Validator<T, TC>;
1074
1123
  /**
1075
1124
  * Gets a default or explicit context.
1076
1125
  * @param explicitContext - Optional explicit context.
@@ -1189,7 +1238,7 @@ export declare interface IMessageAggregator {
1189
1238
  * @example `Infer<typeof Converters.mapOf(Converters.stringArray)>` is `Map<string, string[]>`
1190
1239
  * @beta
1191
1240
  */
1192
- declare type Infer<TCONV> = TCONV extends Converter<infer TTO> ? InnerInferredType<TTO> : never;
1241
+ declare type Infer<TCONV> = TCONV extends Converter<infer TTO, unknown> ? InnerInferredType<TTO> : never;
1193
1242
 
1194
1243
  /**
1195
1244
  * @public
@@ -1210,6 +1259,86 @@ declare class InMemoryLogger extends LoggerBase {
1210
1259
  */
1211
1260
  declare type InnerInferredType<TCONV> = TCONV extends Converter<infer TTO> ? TTO extends Array<infer TTOELEM> ? InnerInferredType<TTOELEM>[] : TTO : TCONV extends Array<infer TELEM> ? InnerInferredType<TELEM>[] : TCONV;
1212
1261
 
1262
+ /**
1263
+ * A readonly `ReadonlyMap<TK, TV>`-like object which reports success or failure
1264
+ * with additional details using the
1265
+ * {@link https://github.com/ErikFortune/fgv/tree/main/libraries/ts-utils#the-result-pattern | result pattern}.
1266
+ * @public
1267
+ */
1268
+ export declare interface IReadOnlyResultMap<TK extends string = string, TV = unknown> {
1269
+ /**
1270
+ * {@inheritdoc Collections.ResultMap.inner}
1271
+ */
1272
+ readonly inner: ReadonlyMap<TK, TV>;
1273
+ /**
1274
+ * {@inheritdoc Collections.ResultMap.size}
1275
+ */
1276
+ readonly size: number;
1277
+ /**
1278
+ * {@inheritdoc Collections.ResultMap.entries}
1279
+ */
1280
+ entries(): MapIterator<KeyValueEntry<TK, TV>>;
1281
+ /**
1282
+ * {@inheritdoc Collections.ResultMap.forEach}
1283
+ */
1284
+ forEach(cb: ResultMapForEachCb, arg?: unknown): void;
1285
+ /**
1286
+ * {@inheritdoc Collections.ResultMap.get}
1287
+ */
1288
+ get(key: TK): DetailedResult<TV, ResultMapResultDetail>;
1289
+ /**
1290
+ * {@inheritdoc Collections.ResultMap.has}
1291
+ */
1292
+ has(key: TK): boolean;
1293
+ /**
1294
+ * {@inheritdoc Collections.ResultMap.keys}
1295
+ */
1296
+ keys(): MapIterator<TK>;
1297
+ /**
1298
+ * {@inheritdoc Collections.ResultMap.values}
1299
+ */
1300
+ values(): MapIterator<TV>;
1301
+ /**
1302
+ * Gets an iterator over the map entries.
1303
+ * @returns An iterator over the map entries.
1304
+ */
1305
+ [Symbol.iterator](): IterableIterator<KeyValueEntry<TK, TV>>;
1306
+ }
1307
+
1308
+ /**
1309
+ * A read-only interface exposing non-mutating methods of a {@link Collections.ResultMapValidator | ResultMapValidator}.
1310
+ * @public
1311
+ */
1312
+ declare interface IReadOnlyResultMapValidator<TK extends string = string, TV = unknown> {
1313
+ /**
1314
+ * {@inheritdoc Collections.ResultMapValidator.validators}
1315
+ */
1316
+ readonly validators: KeyValueValidators<TK, TV>;
1317
+ /**
1318
+ * {@inheritdoc Collections.ResultMapValidator.map}
1319
+ */
1320
+ readonly map: IReadOnlyResultMap<TK, TV>;
1321
+ /**
1322
+ * {@inheritdoc Collections.ResultMap.get}
1323
+ */
1324
+ get(key: string): DetailedResult<TV, ResultMapResultDetail>;
1325
+ /**
1326
+ * {@inheritdoc Collections.ResultMap.has}
1327
+ */
1328
+ has(key: string): boolean;
1329
+ }
1330
+
1331
+ /**
1332
+ * A read-only interface exposing non-mutating methods of a {@link Collections.ValidatingResultMap | ValidatingResultMap}.
1333
+ * @public
1334
+ */
1335
+ declare interface IReadOnlyValidatingResultMap<TK extends string = string, TV = unknown> extends IReadOnlyResultMap<TK, TV> {
1336
+ /**
1337
+ * {@inheritdoc Collections.ValidatingResultMap.validate}
1338
+ */
1339
+ readonly validate: IReadOnlyResultMapValidator<TK, TV>;
1340
+ }
1341
+
1213
1342
  /**
1214
1343
  * Represents the result of some operation of sequence of operations.
1215
1344
  * @remarks
@@ -1352,6 +1481,23 @@ export declare interface IResultLogger {
1352
1481
  error(message: string): void;
1353
1482
  }
1354
1483
 
1484
+ /**
1485
+ * Parameters for constructing a {@link Collections.ResultMap | ResultMap}.
1486
+ * @public
1487
+ */
1488
+ declare interface IResultMapConstructorParams<TK extends string = string, TV = unknown> {
1489
+ entries?: Iterable<KeyValueEntry<TK, TV>>;
1490
+ }
1491
+
1492
+ /**
1493
+ * Parameters for constructing a {@link Collections.ResultMapValidator | ResultMapValidator}.
1494
+ * @public
1495
+ */
1496
+ declare interface IResultMapValidatorCreateParams<TK extends string = string, TV = unknown> {
1497
+ map: ResultMap<TK, TV>;
1498
+ validators: KeyValueValidators<TK, TV>;
1499
+ }
1500
+
1355
1501
  /**
1356
1502
  * Helper function to create a {@link Converter | Converter} from a supplied type guard function.
1357
1503
  * @param description - a description of the thing to be validated for use in error messages
@@ -1373,6 +1519,14 @@ declare function isA<T, TC = unknown>(description: string, guard: TypeGuardWithC
1373
1519
  */
1374
1520
  declare function isA_2<T, TC>(description: string, guard: TypeGuardWithContext<T, TC>, params?: Omit<TypeGuardValidatorConstructorParams<T, TC>, 'description' | 'guard'>): TypeGuardValidator<T, TC>;
1375
1521
 
1522
+ /**
1523
+ * Determines if a supplied value is an iterable object or some other type.
1524
+ * @param value - The value to be tested.
1525
+ * @returns `true` if the value is an iterable object, `false` otherwise.
1526
+ * @public
1527
+ */
1528
+ declare function isIterable<TE = unknown, TI extends Iterable<TE> = Iterable<TE>, TO = unknown>(value: TI | TO): value is TI;
1529
+
1376
1530
  /**
1377
1531
  * Helper type-guard function to report whether a specified key is present in
1378
1532
  * a supplied object.
@@ -1383,13 +1537,22 @@ declare function isA_2<T, TC>(description: string, guard: TypeGuardWithContext<T
1383
1537
  */
1384
1538
  export declare function isKeyOf<T extends object>(key: string | number | symbol, item: T): key is keyof T;
1385
1539
 
1540
+ /**
1541
+ * Parameters for constructing a {@link Collections.ResultMap | ResultMap}.
1542
+ * @public
1543
+ */
1544
+ declare interface IValidatingResultMapConstructorParams<TK extends string = string, TV = unknown> {
1545
+ entries?: Iterable<KeyValueEntry<string, unknown>>;
1546
+ validators: KeyValueValidators<TK, TV>;
1547
+ }
1548
+
1386
1549
  /**
1387
1550
  * Options for {@link Converters.(recordOf:3) | Converters.recordOf} and
1388
1551
  * {@link Converters.(mapOf:3) | Converters.mapOf}
1389
1552
  * helper functions.
1390
1553
  * @public
1391
1554
  */
1392
- declare interface KeyedConverterOptions<T extends string = string, TC = undefined> {
1555
+ declare interface KeyedConverterOptions<T extends string = string, TC = unknown> {
1393
1556
  /**
1394
1557
  * if `onError` is `'fail'` (default), then the entire conversion fails if any key or element
1395
1558
  * cannot be converted. If `onError` is `'ignore'`, failing elements are silently ignored.
@@ -1410,6 +1573,69 @@ declare interface KeyedConverterOptions<T extends string = string, TC = undefine
1410
1573
  */
1411
1574
  declare type KeyedThingFactory<TS, TD, TK extends string = string> = (key: TK, thing: TS) => Result<TD>;
1412
1575
 
1576
+ /**
1577
+ * Generic key-value entry.
1578
+ * @public
1579
+ */
1580
+ declare type KeyValueEntry<TK extends string = string, TV = unknown> = [TK, TV];
1581
+
1582
+ /**
1583
+ * Helper class for validating key-value pairs.
1584
+ * @public
1585
+ */
1586
+ declare class KeyValueValidators<TK extends string = string, TV = unknown> {
1587
+ /**
1588
+ * Required key validator or converter.
1589
+ */
1590
+ readonly key: Validator<TK, unknown> | Converter<TK, unknown>;
1591
+ /**
1592
+ * Required value validator or converter.
1593
+ */
1594
+ readonly value: Validator<TV, unknown> | Converter<TV, unknown>;
1595
+ /**
1596
+ * Optional entry validator or converter. If no entry validator is provided,
1597
+ * an entry is considered valid if both key and value are valid.
1598
+ */
1599
+ readonly entry?: Validator<KeyValueEntry<TK, TV>, unknown> | Converter<KeyValueEntry<TK, TV>, unknown>;
1600
+ /**
1601
+ * Constructs a new key-value validator.
1602
+ * @param key - Required key validator or converter.
1603
+ * @param value - Required value validator or converter.
1604
+ * @param entry - Optional entry validator or converter. If no entry validator is provided,
1605
+ * an entry is considered valid if both key and value are valid.
1606
+ */
1607
+ constructor(key: Validator<TK, unknown> | Converter<TK, unknown>, value: Validator<TV, unknown> | Converter<TV, unknown>, entry?: Validator<KeyValueEntry<TK, TV>, unknown> | Converter<KeyValueEntry<TK, TV>, unknown>);
1608
+ /**
1609
+ * Validates a supplied unknown as a valid key value.
1610
+ * @param key - The unknown to be validated.
1611
+ * @returns `Success` with the validated key value and 'success' detail if the key is valid,
1612
+ * or `Failure` with an error message and 'invalid-key' detail if the key is invalid.
1613
+ */
1614
+ validateKey(key: unknown): DetailedResult<TK, ResultMapResultDetail>;
1615
+ /**
1616
+ * Validates a supplied unknown as a valid value.
1617
+ * @param key - The unknown to be validated.
1618
+ * @returns `Success` with the validated value and 'success' detail if the value is valid,
1619
+ * or `Failure` with an error message and 'invalid-value' detail if the value is invalid.
1620
+ */
1621
+ validateValue(key: unknown): DetailedResult<TV, ResultMapResultDetail>;
1622
+ /**
1623
+ * Validates a supplied unknown as a valid key-value pair.
1624
+ * @param entry - The unknown to be validated.
1625
+ * @returns `Success` with the validated key-value pair and 'success' detail if the entry
1626
+ * is valid, or `Failure` with an error message and 'invalid-key' or 'invalid-value' detail if
1627
+ * the entry is invalid
1628
+ */
1629
+ validateEntry(entry: unknown): DetailedResult<KeyValueEntry<TK, TV>, ResultMapResultDetail>;
1630
+ /**
1631
+ * Validates a supplied iterable of unknowns as valid key-value pairs.
1632
+ * @param entries - The iterable of unknowns to be validated.
1633
+ * @returns `Success` with an array of validated key-value pairs if all entries are valid,
1634
+ * or `Failure` with an error message if any entry is invalid.
1635
+ */
1636
+ validateEntries(entries: Iterable<unknown>): Result<KeyValueEntry<TK, TV>[]>;
1637
+ }
1638
+
1413
1639
  /**
1414
1640
  * Helper function to create a {@link Converter | Converter} which converts `unknown` to some supplied literal value. Succeeds with
1415
1641
  * the supplied value if an identity comparison succeeds, fails otherwise.
@@ -1417,7 +1643,7 @@ declare type KeyedThingFactory<TS, TD, TK extends string = string> = (key: TK, t
1417
1643
  * @returns A {@link Converter | Converter} which returns the supplied value on success.
1418
1644
  * @public
1419
1645
  */
1420
- declare function literal<T>(value: T): Converter<T, unknown>;
1646
+ declare function literal<T, TC = unknown>(value: T): Converter<T, TC>;
1421
1647
 
1422
1648
  /**
1423
1649
  * Helper function to create a {@link Validation.Validator} which validates a literal value.
@@ -1501,7 +1727,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1501
1727
 
1502
1728
  /**
1503
1729
  * A helper function to create a {@link Converter | Converter} which converts the `string`-keyed properties
1504
- * using a supplied {@link Converter | Converter<T>} or {@link Validator | Validator<T>} to produce a
1730
+ * using a supplied {@link Converter | Converter<T, TC>} or {@link Validator | Validator<T>} to produce a
1505
1731
  * `Map<string, T>`.
1506
1732
  * @remarks
1507
1733
  * The resulting converter fails conversion if any element cannot be converted.
@@ -1511,11 +1737,11 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1511
1737
  * {@label WITH_DEFAULT}
1512
1738
  * @public
1513
1739
  */
1514
- declare function mapOf<T, TC = undefined, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>): Converter<Map<TK, T>, TC>;
1740
+ declare function mapOf<T, TC = unknown, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>): Converter<Map<TK, T>, TC>;
1515
1741
 
1516
1742
  /**
1517
1743
  * A helper function to create a {@link Converter | Converter} which converts the `string`-keyed properties
1518
- * using a supplied {@link Converter | Converter<T>} or {@link Validator | Validator<T>} to produce a
1744
+ * using a supplied {@link Converter | Converter<T, TC>} or {@link Validator | Validator<T>} to produce a
1519
1745
  * `Map<string, T>` and specified handling of elements that cannot be converted.
1520
1746
  * @remarks
1521
1747
  * if `onError` is `'fail'` (default), then the entire conversion fails if any key or element
@@ -1526,11 +1752,11 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1526
1752
  * {@label WITH_ON_ERROR}
1527
1753
  * @public
1528
1754
  */
1529
- declare function mapOf<T, TC = undefined, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>, onError: 'fail' | 'ignore'): Converter<Map<TK, T>, TC>;
1755
+ declare function mapOf<T, TC = unknown, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>, onError: 'fail' | 'ignore'): Converter<Map<TK, T>, TC>;
1530
1756
 
1531
1757
  /**
1532
1758
  * A helper function to create a {@link Converter | Converter} which converts the `string`-keyed properties
1533
- * using a supplied {@link Converter | Converter<T>} or {@link Validator | Validator<T>} to produce
1759
+ * using a supplied {@link Converter | Converter<T, TC>} or {@link Validator | Validator<T>} to produce
1534
1760
  * a `Map<TK,T>`.
1535
1761
  * @remarks
1536
1762
  * If present, the supplied {@link Converters.KeyedConverterOptions | options} can provide a strongly-typed
@@ -1543,7 +1769,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1543
1769
  * {@label WITH_OPTIONS}
1544
1770
  * @public
1545
1771
  */
1546
- declare function mapOf<T, TC = undefined, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>, options: KeyedConverterOptions<TK, TC>): Converter<Map<TK, T>, TC>;
1772
+ declare function mapOf<T, TC = unknown, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>, options: KeyedConverterOptions<TK, TC>): Converter<Map<TK, T>, TC>;
1547
1773
 
1548
1774
  /**
1549
1775
  * Helper function to create a {@link Converter | Converter} which converts `unknown` to one of a set of supplied enumerated
@@ -1558,7 +1784,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1558
1784
  * @returns A {@link Converter | Converter} which applies the mapping and yields `<T>` on success.
1559
1785
  * @public
1560
1786
  */
1561
- declare function mappedEnumeratedValue<T>(map: [T, unknown[]][], message?: string): Converter<T, undefined>;
1787
+ declare function mappedEnumeratedValue<T, TC = unknown>(map: [T, unknown[]][], message?: string): Converter<T, TC>;
1562
1788
 
1563
1789
  /**
1564
1790
  * Aggregates successful result values from a collection of {@link Result | Result<T>}.
@@ -1701,7 +1927,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1701
1927
  * Numbers and strings with a numeric format succeed. Anything else fails.
1702
1928
  * @public
1703
1929
  */
1704
- declare const number: Converter<number, undefined>;
1930
+ declare const number: Converter<number, unknown>;
1705
1931
 
1706
1932
  /**
1707
1933
  * A {@link Validation.Classes.NumberValidator | NumberValidator} which validates a number in place.
@@ -1716,7 +1942,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1716
1942
  * of numbers, returns {@link Failure | Failure} with an error message otherwise.
1717
1943
  * @public
1718
1944
  */
1719
- declare const numberArray: Converter<number[]>;
1945
+ declare const numberArray: Converter<number[], unknown>;
1720
1946
 
1721
1947
  /**
1722
1948
  * An in-place {@link Validation.Validator | Validator} for `number` values.
@@ -1745,8 +1971,8 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1745
1971
  declare type NumberValidatorConstructorParams<T extends number = number, TC = unknown> = GenericValidatorConstructorParams<T, TC>;
1746
1972
 
1747
1973
  /**
1748
- * Helper function to create a {@link Conversion.ObjectConverter | ObjectConverter<T>} which converts an object
1749
- * without changing shape, given a {@link Conversion.FieldConverters | FieldConverters<T>} and an optional
1974
+ * Helper function to create a {@link Conversion.ObjectConverter | ObjectConverter<T, TC>} which converts an object
1975
+ * without changing shape, given a {@link Conversion.FieldConverters | FieldConverters<T, TC>} and an optional
1750
1976
  * {@link Conversion.ObjectConverterOptions | ObjectConverterOptions<T>} to further refine conversion behavior.
1751
1977
  * @remarks
1752
1978
  * By default, if all of the requested fields exist and can be converted, returns {@link Success | Success}
@@ -1756,7 +1982,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1756
1982
  *
1757
1983
  * Fields that succeed but convert to undefined are omitted from the result object but do not
1758
1984
  * fail the conversion.
1759
- * @param properties - An {@link Conversion.FieldConverters | FieldConverters<T>} defining the shape of the
1985
+ * @param properties - An {@link Conversion.FieldConverters | FieldConverters<T, TC>} defining the shape of the
1760
1986
  * source object and {@link Converter | converters} to be applied to each properties.
1761
1987
  * @param options - An {@link Conversion.ObjectConverterOptions | ObjectConverterOptions<T>} containing options
1762
1988
  * for the object converter.
@@ -1764,11 +1990,11 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1764
1990
  * {@label WITH_OPTIONS}
1765
1991
  * @public
1766
1992
  */
1767
- declare function object<T>(properties: FieldConverters<T>, options?: ObjectConverterOptions<T>): ObjectConverter<T>;
1993
+ declare function object<T, TC = unknown>(properties: FieldConverters<T, TC>, options?: ObjectConverterOptions<T>): ObjectConverter<T, TC>;
1768
1994
 
1769
1995
  /**
1770
- * Helper function to create a {@link Conversion.ObjectConverter | ObjectConverter<T>} which converts an object
1771
- * without changing shape, given a {@link Conversion.FieldConverters | FieldConverters<T>} and a set of
1996
+ * Helper function to create a {@link Conversion.ObjectConverter | ObjectConverter<T, TC>} which converts an object
1997
+ * without changing shape, given a {@link Conversion.FieldConverters | FieldConverters<T, TC>} and a set of
1772
1998
  * optional properties.
1773
1999
  * @remarks
1774
2000
  * By default, if all of the requested fields exist and can be converted, returns {@link Success | Success}
@@ -1778,7 +2004,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1778
2004
  *
1779
2005
  * Fields that succeed but convert to undefined are omitted from the result object but do not
1780
2006
  * fail the conversion.
1781
- * @param properties - An {@link Conversion.FieldConverters | FieldConverters<T>} defining the shape of the
2007
+ * @param properties - An {@link Conversion.FieldConverters | FieldConverters<T, TC>} defining the shape of the
1782
2008
  * source object and {@link Converter | converters} to be applied to each properties.
1783
2009
  * @param optional - An array of `(keyof T)` listing the keys to be considered optional.
1784
2010
  * {@label WITH_KEYS}
@@ -1786,7 +2012,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1786
2012
  * @public
1787
2013
  * @deprecated Use {@link Converters.(object:1) | Converters.object(fields, options)} instead.
1788
2014
  */
1789
- declare function object<T>(properties: FieldConverters<T>, optional: (keyof T)[]): ObjectConverter<T>;
2015
+ declare function object<T, TC = unknown>(properties: FieldConverters<T, TC>, optional: (keyof T)[]): ObjectConverter<T, TC>;
1790
2016
 
1791
2017
  /**
1792
2018
  * Helper function to create a {@link Validation.Classes.ObjectValidator | ObjectValidator} which validates
@@ -1815,13 +2041,13 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1815
2041
  /**
1816
2042
  * Fields converted by this {@link Conversion.ObjectConverter | ObjectConverter}.
1817
2043
  */
1818
- readonly fields: FieldConverters<T>;
2044
+ readonly fields: FieldConverters<T, TC>;
1819
2045
  /**
1820
2046
  * Options used to initialize this {@link Conversion.ObjectConverter | ObjectConverter}.
1821
2047
  */
1822
2048
  readonly options: ObjectConverterOptions<T>;
1823
2049
  /**
1824
- * Constructs a new {@link Conversion.ObjectConverter | ObjectConverter<T>} using options
2050
+ * Constructs a new {@link Conversion.ObjectConverter | ObjectConverter<T, TC>} using options
1825
2051
  * supplied in a {@link Conversion.ObjectConverterOptions | ObjectConverterOptions<T>}.
1826
2052
  * @param fields - A {@link Conversion.FieldConverters | FieldConverters<T>} containing
1827
2053
  * a {@link Converter} for each field
@@ -1830,7 +2056,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
1830
2056
  */
1831
2057
  constructor(fields: FieldConverters<T, TC>, options?: ObjectConverterOptions<T>);
1832
2058
  /**
1833
- * Constructs a new {@link Conversion.ObjectConverter | ObjectConverter<T>} with optional
2059
+ * Constructs a new {@link Conversion.ObjectConverter | ObjectConverter<T, TC>} with optional
1834
2060
  * properties specified as an array of `keyof T`.
1835
2061
  * @param fields - A {@link Conversion.FieldConverters | FieldConverters<T>} containing
1836
2062
  * a {@link Converter} for each field.
@@ -2086,7 +2312,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2086
2312
  * with value `undefined`.
2087
2313
  * @public
2088
2314
  */
2089
- declare const optionalBoolean: Converter<boolean | undefined>;
2315
+ declare const optionalBoolean: Converter<boolean | undefined, unknown>;
2090
2316
 
2091
2317
  /**
2092
2318
  * A helper function to create a {@link Converter | Converter} which extracts and converts an optional element from an array.
@@ -2097,10 +2323,10 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2097
2323
  * is not an array, if the requested index is negative, or if the element cannot be converted.
2098
2324
  * @param index - The index of the element to be extracted.
2099
2325
  * @param converter - A {@link Converter | Converter} or {@link Validator | Validator} used for the extracted element.
2100
- * @returns A {@link Converter | Converter<T>} which extracts the specified element from an array.
2326
+ * @returns A {@link Converter | Converter<T, TC>} which extracts the specified element from an array.
2101
2327
  * @public
2102
2328
  */
2103
- declare function optionalElement<T, TC = undefined>(index: number, converter: Converter<T, TC> | Validator<T, TC>): Converter<T | undefined, TC>;
2329
+ declare function optionalElement<T, TC = unknown>(index: number, converter: Converter<T, TC> | Validator<T, TC>): Converter<T | undefined, TC>;
2104
2330
 
2105
2331
  /**
2106
2332
  * A helper function to create a {@link Converter | Converter} which extracts and convert a property specified
@@ -2114,7 +2340,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2114
2340
  * @param converter - {@link Converter | Converter} or {@link Validator | Validator} to use for the extracted field.
2115
2341
  * @public
2116
2342
  */
2117
- declare function optionalField<T, TC = undefined>(name: string, converter: Converter<T, TC> | Validator<T, TC>): Converter<T | undefined, TC>;
2343
+ declare function optionalField<T, TC = unknown>(name: string, converter: Converter<T, TC> | Validator<T, TC>): Converter<T | undefined, TC>;
2118
2344
 
2119
2345
  /**
2120
2346
  * Applies a factory method to convert an optional `ReadonlyMap<string, TS>` into a `Record<string, TD>`
@@ -2143,7 +2369,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2143
2369
  * Anything else returns {@link Success | Success} with value `undefined`.
2144
2370
  * @public
2145
2371
  */
2146
- declare const optionalNumber: Converter<number | undefined>;
2372
+ declare const optionalNumber: Converter<number | undefined, unknown>;
2147
2373
 
2148
2374
  /**
2149
2375
  * Applies a factory method to convert an optional `Record<TK, TS>` into a `Map<TK, TD>`, or `undefined`.
@@ -2249,7 +2475,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2249
2475
 
2250
2476
  /**
2251
2477
  * A helper function to create a {@link Converter | Converter} which converts the `string`-keyed
2252
- * properties using a supplied {@link Converter | Converter<T>} or {@link Validator | Validator<T>} to
2478
+ * properties using a supplied {@link Converter | Converter<T, TC>} or {@link Validator | Validator<T>} to
2253
2479
  * produce a `Record<string, T>`.
2254
2480
  * @remarks
2255
2481
  * The resulting converter fails conversion if any element cannot be converted.
@@ -2259,11 +2485,11 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2259
2485
  * {@label WITH_DEFAULT}
2260
2486
  * @public
2261
2487
  */
2262
- declare function recordOf<T, TC = undefined, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>): Converter<Record<TK, T>, TC>;
2488
+ declare function recordOf<T, TC = unknown, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>): Converter<Record<TK, T>, TC>;
2263
2489
 
2264
2490
  /**
2265
2491
  * A helper function to create a {@link Converter | Converter} which converts the `string`-keyed properties
2266
- * using a supplied {@link Converter | Converter<T>} or {@link Validator | Validator<T>} to produce a
2492
+ * using a supplied {@link Converter | Converter<T, TC>} or {@link Validator | Validator<T>} to produce a
2267
2493
  * `Record<string, T>` and optionally specified handling of elements that cannot be converted.
2268
2494
  * @remarks
2269
2495
  * if `onError` is `'fail'` (default), then the entire conversion fails if any key or element
@@ -2274,11 +2500,11 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2274
2500
  * {@label WITH_ON_ERROR}
2275
2501
  * @public
2276
2502
  */
2277
- declare function recordOf<T, TC = undefined, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>, onError: 'fail' | 'ignore'): Converter<Record<TK, T>, TC>;
2503
+ declare function recordOf<T, TC = unknown, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>, onError: 'fail' | 'ignore'): Converter<Record<TK, T>, TC>;
2278
2504
 
2279
2505
  /**
2280
2506
  * A helper function to create a {@link Converter | Converter} or which converts the `string`-keyed properties
2281
- * using a supplied {@link Converter | Converter<T>} or {@link Validator | Validator<T>} to produce a
2507
+ * using a supplied {@link Converter | Converter<T, TC>} or {@link Validator | Validator<T>} to produce a
2282
2508
  * `Record<TK, T>`.
2283
2509
  * @remarks
2284
2510
  * If present, the supplied {@link Converters.KeyedConverterOptions | options} can provide a strongly-typed
@@ -2290,7 +2516,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2290
2516
  * {@label WITH_OPTIONS}
2291
2517
  * @public
2292
2518
  */
2293
- declare function recordOf<T, TC = undefined, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>, options: KeyedConverterOptions<TK, TC>): Converter<Record<TK, T>, TC>;
2519
+ declare function recordOf<T, TC = unknown, TK extends string = string>(converter: Converter<T, TC> | Validator<T, TC>, options: KeyedConverterOptions<TK, TC>): Converter<Record<TK, T>, TC>;
2294
2520
 
2295
2521
  /**
2296
2522
  * Applies a factory method to convert a `Record<TK, TS>` into a `Map<TK, TD>`.
@@ -2317,6 +2543,211 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2317
2543
  */
2318
2544
  export declare type ResultDetailType<T> = T extends DetailedResult<unknown, infer TD> ? TD : never;
2319
2545
 
2546
+ /**
2547
+ * A {@link Collections.ResultMap | ResultMap} class as a `Map<TK, TV>`-like object which
2548
+ * reports success or failure with additional details using the
2549
+ * {@link https://github.com/ErikFortune/fgv/tree/main/libraries/ts-utils#the-result-pattern | result pattern}.
2550
+ * @public
2551
+ */
2552
+ export declare class ResultMap<TK extends string = string, TV = unknown> implements IReadOnlyResultMap<TK, TV> {
2553
+ /**
2554
+ * Readonly raw access to the inner `Map<TK, TV>` object.
2555
+ */
2556
+ get inner(): ReadonlyMap<TK, TV>;
2557
+ /**
2558
+ * Protected raw access to the inner `Map<TK, TV>` object.
2559
+ * @public
2560
+ */
2561
+ protected readonly _inner: Map<TK, TV>;
2562
+ /**
2563
+ * Constructs a new {@link Collections.ResultMap | ResultMap}.
2564
+ * @param iterable - An iterable to initialize the map.
2565
+ */
2566
+ constructor(iterable?: Iterable<KeyValueEntry<TK, TV>>);
2567
+ /**
2568
+ * Constructs a new {@link Collections.ResultMap | ResultMap}.
2569
+ * @param params - An optional set of parameters to configure the map.
2570
+ */
2571
+ constructor(params: IResultMapConstructorParams);
2572
+ /**
2573
+ * Creates a new {@link Collections.ResultMap | ResultMap}.
2574
+ * @param elements - An optional iterable to initialize the map.
2575
+ * @returns `Success` with the new map, or `Failure` with error details
2576
+ * if an error occurred.
2577
+ * @public
2578
+ */
2579
+ static create<TK extends string = string, TV = unknown>(elements: Iterable<KeyValueEntry<TK, TV>>): Result<ResultMap<TK, TV>>;
2580
+ /**
2581
+ * Creates a new {@link Collections.ResultMap | ResultMap}.
2582
+ * @param params - An optional set of parameters to configure the map.
2583
+ * @returns `Success` with the new map, or `Failure` with error details
2584
+ * if an error occurred.
2585
+ * @public
2586
+ */
2587
+ static create<TK extends string = string, TV = unknown>(params?: IResultMapConstructorParams<TK, TV>): Result<ResultMap<TK, TV>>;
2588
+ /**
2589
+ * Sets a key/value pair in the map if the key does not already exist.
2590
+ * @param key - The key to set.
2591
+ * @param value - The value to set.
2592
+ * @returns `Success` with the value and detail `added` if the key was added,
2593
+ * `Failure` with detail `exists` if the key already exists. Fails with detail
2594
+ * 'invalid-key' or 'invalid-value' and an error message if either is invalid.
2595
+ */
2596
+ add(key: TK, value: TV): DetailedResult<TV, ResultMapResultDetail>;
2597
+ /**
2598
+ * Clears the map.
2599
+ */
2600
+ clear(): void;
2601
+ /**
2602
+ * Deletes a key from the map.
2603
+ * @param key - The key to delete.
2604
+ * @returns `Success` with the previous value and the detail 'deleted'
2605
+ * if the key was found and deleted, `Failure` with detail 'not-found'
2606
+ * if the key was not found, or with detail 'invalid-key' if the key is invalid.
2607
+ */
2608
+ delete(key: TK): DetailedResult<TV, ResultMapResultDetail>;
2609
+ /**
2610
+ * Returns an iterator over the map entries.
2611
+ * @returns An iterator over the map entries.
2612
+ */
2613
+ entries(): MapIterator<KeyValueEntry<TK, TV>>;
2614
+ /**
2615
+ * Calls a function for each entry in the map.
2616
+ * @param cb - The function to call for each entry.
2617
+ * @param arg - An optional argument to pass to the callback.
2618
+ */
2619
+ forEach(cb: ResultMapForEachCb<TK, TV>, arg?: unknown): void;
2620
+ /**
2621
+ * Gets a value from the map.
2622
+ * @param key - The key to retrieve.
2623
+ * @returns `Success` with the value and detail `exists` if the key was found,
2624
+ * `Failure` with detail `not-found` if the key was not found or with detail
2625
+ * `invalid-key` if the key is invalid.
2626
+ */
2627
+ get(key: TK): DetailedResult<TV, ResultMapResultDetail>;
2628
+ /**
2629
+ * Gets a value from the map, or adds a supplied value it if it does not exist.
2630
+ * @param key - The key to retrieve.
2631
+ * @param value - The value to add if the key does not exist.
2632
+ * @returns `Success` with the value and detail `exists` if the key was found,
2633
+ * `Success` with the value and detail `added` if the key was not found and added.
2634
+ * Fails with detail 'invalid-key' or 'invalid-value' and an error message if either
2635
+ * is invalid.
2636
+ */
2637
+ getOrAdd(key: TK, value: TV): DetailedResult<TV, ResultMapResultDetail>;
2638
+ /**
2639
+ * Returns `true` if the map contains a key.
2640
+ * @param key - The key to check.
2641
+ * @returns `true` if the key exists, `false` otherwise.
2642
+ */
2643
+ has(key: TK): boolean;
2644
+ /**
2645
+ * Returns an iterator over the map keys.
2646
+ * @returns An iterator over the map keys.
2647
+ */
2648
+ keys(): MapIterator<TK>;
2649
+ /**
2650
+ * Sets a key/value pair in the map.
2651
+ * @param key - The key to set.
2652
+ * @param value - The value to set.
2653
+ * @returns `Success` with the new value and the detail `updated` if the
2654
+ * key was found and updated, `Success` with the new value and detail
2655
+ * `added` if the key was not found and added. Fails with detail
2656
+ * 'invalid-key' or 'invalid-value' and an error message if either is invalid.
2657
+ */
2658
+ set(key: TK, value: TV): DetailedResult<TV, ResultMapResultDetail>;
2659
+ /**
2660
+ * Returns the number of entries in the map.
2661
+ */
2662
+ get size(): number;
2663
+ /**
2664
+ * Updates an existing key in the map - the map is not updated if the key does
2665
+ * not exist.
2666
+ * @param key - The key to update.
2667
+ * @param value - The value to set.
2668
+ * @returns `Success` with the value and detail 'exists' if the key was found
2669
+ * and the value updated, `Failure` an error message and with detail `not-found`
2670
+ * if the key was not found, or with detail 'invalid-key' or 'invalid-value'
2671
+ * if either is invalid.
2672
+ */
2673
+ update(key: TK, value: TV): DetailedResult<TV, ResultMapResultDetail>;
2674
+ /**
2675
+ * Returns an iterator over the map values.
2676
+ * @returns An iterator over the map values.
2677
+ */
2678
+ values(): MapIterator<TV>;
2679
+ /**
2680
+ * Gets an iterator over the map entries.
2681
+ * @returns An iterator over the map entries.
2682
+ */
2683
+ [Symbol.iterator](): IterableIterator<KeyValueEntry<TK, TV>>;
2684
+ /**
2685
+ * Gets a readonly version of this map.
2686
+ * @returns A readonly version of this map.
2687
+ */
2688
+ toReadOnly(): IReadOnlyResultMap<TK, TV>;
2689
+ }
2690
+
2691
+ /**
2692
+ * Callback for {@link Collections.ResultMap | ResultMap} `forEach` method.
2693
+ * @public
2694
+ */
2695
+ declare type ResultMapForEachCb<TK extends string = string, TE = unknown> = (value: TE, key: TK, map: IReadOnlyResultMap<TK, TE>, thisArg?: unknown) => void;
2696
+
2697
+ /**
2698
+ * Additional success or failure details for {@link Collections.ResultMap | ResultMap} calls.
2699
+ * @public
2700
+ */
2701
+ declare type ResultMapResultDetail = 'added' | 'deleted' | 'exists' | 'invalid-key' | 'invalid-value' | 'not-found' | 'success' | 'updated';
2702
+
2703
+ /**
2704
+ * A {@link Collections.ResultMap | ResultMap} wrapper which validates weakly-typed keys
2705
+ * before calling the wrapped result map.
2706
+ * @public
2707
+ */
2708
+ declare class ResultMapValidator<TK extends string = string, TV = unknown> implements IReadOnlyResultMapValidator<TK, TV> {
2709
+ readonly validators: KeyValueValidators<TK, TV>;
2710
+ get map(): IReadOnlyResultMap<TK, TV>;
2711
+ protected _map: ResultMap<TK, TV>;
2712
+ /**
2713
+ * Constructs a new {@link Collections.ValidatingResultMap | ValidatingResultMap}.
2714
+ * @param params - Required parameters for constructing the map.
2715
+ */
2716
+ constructor(params: IResultMapValidatorCreateParams<TK, TV>);
2717
+ /**
2718
+ * {@inheritdoc Collections.ResultMap.add}
2719
+ */
2720
+ add(key: string, value: unknown): DetailedResult<TV, ResultMapResultDetail>;
2721
+ /**
2722
+ * {@inheritdoc Collections.ResultMap.delete}
2723
+ */
2724
+ delete(key: string): DetailedResult<TV, ResultMapResultDetail>;
2725
+ /**
2726
+ * {@inheritdoc Collections.ResultMap.get}
2727
+ */
2728
+ get(key: string): DetailedResult<TV, ResultMapResultDetail>;
2729
+ /**
2730
+ * {@inheritdoc Collections.ResultMap.getOrAdd}
2731
+ */
2732
+ getOrAdd(key: string, value: unknown): DetailedResult<TV, ResultMapResultDetail>;
2733
+ /**
2734
+ * {@inheritdoc Collections.ResultMap.has}
2735
+ */
2736
+ has(key: string): boolean;
2737
+ /**
2738
+ * {@inheritdoc Collections.ResultMap.set}
2739
+ */
2740
+ set(key: string, value: unknown): DetailedResult<TV, ResultMapResultDetail>;
2741
+ /**
2742
+ * {@inheritdoc Collections.ResultMap.update}
2743
+ */
2744
+ update(key: string, value: unknown): DetailedResult<TV, ResultMapResultDetail>;
2745
+ /**
2746
+ * Gets a read-only version of this validator.
2747
+ */
2748
+ toReadOnly(): IReadOnlyResultMapValidator<TK, TV>;
2749
+ }
2750
+
2320
2751
  /**
2321
2752
  * Type inference to determine the result type of an {@link Result}.
2322
2753
  * @beta
@@ -2325,7 +2756,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2325
2756
 
2326
2757
  /**
2327
2758
  * Helper function to create a {@link Conversion.ObjectConverter | ObjectConverter} which converts an object
2328
- * without changing shape, a {@link Conversion.FieldConverters | FieldConverters<T>} and an optional
2759
+ * without changing shape, a {@link Conversion.FieldConverters | FieldConverters<T, TC>} and an optional
2329
2760
  * {@link Converters.StrictObjectConverterOptions | StrictObjectConverterOptions<T>} to further refine
2330
2761
  * conversion behavior.
2331
2762
  *
@@ -2341,11 +2772,11 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2341
2772
  * {@label WITH_OPTIONS}
2342
2773
  * @public
2343
2774
  */
2344
- declare function strictObject<T>(properties: FieldConverters<T>, options?: StrictObjectConverterOptions<T>): ObjectConverter<T>;
2775
+ declare function strictObject<T, TC = unknown>(properties: FieldConverters<T, TC>, options?: StrictObjectConverterOptions<T>): ObjectConverter<T, TC>;
2345
2776
 
2346
2777
  /**
2347
2778
  * Helper function to create a {@link Conversion.ObjectConverter | ObjectConverter} which converts an object
2348
- * without changing shape, a {@link Conversion.FieldConverters | FieldConverters<T>} and an optional
2779
+ * without changing shape, a {@link Conversion.FieldConverters | FieldConverters<T, TC>} and an optional
2349
2780
  * {@link Converters.StrictObjectConverterOptions | StrictObjectConverterOptions<T>} to further refine
2350
2781
  * conversion behavior.
2351
2782
  *
@@ -2362,7 +2793,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2362
2793
  * @deprecated Use {@link Converters.(strictObject:1) | Converters.strictObject(options)} instead.
2363
2794
  * @public
2364
2795
  */
2365
- declare function strictObject<T>(properties: FieldConverters<T>, optional: (keyof T)[]): ObjectConverter<T>;
2796
+ declare function strictObject<T, TC = unknown>(properties: FieldConverters<T, TC>, optional: (keyof T)[]): ObjectConverter<T, TC>;
2366
2797
 
2367
2798
  /**
2368
2799
  * Options for the {@link Converters.(strictObject:1)} helper function.
@@ -2390,7 +2821,7 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2390
2821
  * of strings, returns {@link Failure | Failure} with an error message otherwise.
2391
2822
  * @public
2392
2823
  */
2393
- declare const stringArray: Converter<string[]>;
2824
+ declare const stringArray: Converter<string[], unknown>;
2394
2825
 
2395
2826
  /**
2396
2827
  * The {@link Conversion.StringConverter | StringConverter} class extends
@@ -2706,6 +3137,13 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2706
3137
  */
2707
3138
  declare type TypeGuardWithContext<T, TC = unknown> = (from: unknown, context?: TC) => from is T;
2708
3139
 
3140
+ declare namespace Utils {
3141
+ export {
3142
+ isIterable,
3143
+ KeyValueValidators
3144
+ }
3145
+ }
3146
+
2709
3147
  /**
2710
3148
  * Helper function to create a {@link Converter | Converter} from any {@link Validation.Validator}
2711
3149
  * @param validator - the validator to be wrapped
@@ -2723,10 +3161,52 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2723
3161
  * information otherwise.
2724
3162
  * @param validator - A validator function to determine if the converted value is valid.
2725
3163
  * @param description - A description of the validated type for use in error messages.
2726
- * @returns A new {@link Converter | Converter<T>} which applies the supplied validation.
3164
+ * @returns A new {@link Converter | Converter<T, TC>} which applies the supplied validation.
2727
3165
  * @public
2728
3166
  */
2729
- declare function validateWith<T, TC = undefined>(validator: (from: unknown) => from is T, description?: string): Converter<T, TC>;
3167
+ declare function validateWith<T, TC = unknown>(validator: (from: unknown) => from is T, description?: string): Converter<T, TC>;
3168
+
3169
+ /**
3170
+ * A {@link Collections.ResultMap | ResultMap} with a {@link Collections.ResultMapValidator | validator}
3171
+ * property that enables validated use of the underlying map with weakly-typed keys and values.
3172
+ * @public
3173
+ */
3174
+ export declare class ValidatingResultMap<TK extends string = string, TV = unknown> extends ResultMap<TK, TV> implements IReadOnlyValidatingResultMap<TK, TV> {
3175
+ /**
3176
+ * A {@link Collections.ResultMapValidator | ResultMapValidator} which validates keys and values
3177
+ * before inserting them into this collection.
3178
+ */
3179
+ readonly validate: ResultMapValidator<TK, TV>;
3180
+ /**
3181
+ * Constructs a new {@link Collections.ValidatingResultMap | ValidatingResultMap}.
3182
+ * @param params - Required parameters for constructing the map.
3183
+ */
3184
+ constructor(params: IValidatingResultMapConstructorParams<TK, TV>);
3185
+ /**
3186
+ * Creates a new {@link Collections.ValidatingResultMap | ValidatingResultMap} instance.
3187
+ * @param params - Required parameters for constructing the map.
3188
+ * @returns `Success` with the new map if successful, `Failure` otherwise.
3189
+ * @public
3190
+ */
3191
+ static createValidating<TK extends string = string, TV = unknown>(params: IValidatingResultMapConstructorParams<TK, TV>): Result<ValidatingResultMap<TK, TV>>;
3192
+ /**
3193
+ * {@inheritdoc Collections.ResultMap.add}
3194
+ */
3195
+ add(key: TK, value: TV): DetailedResult<TV, ResultMapResultDetail>;
3196
+ /**
3197
+ * {@inheritdoc Collections.ResultMap.getOrAdd}
3198
+ */
3199
+ getOrAdd(key: TK, value: TV): DetailedResult<TV, ResultMapResultDetail>;
3200
+ set(key: TK, value: TV): DetailedResult<TV, ResultMapResultDetail>;
3201
+ /**
3202
+ * {@inheritdoc Collections.ResultMap.update}
3203
+ */
3204
+ update(key: TK, value: TV): DetailedResult<TV, ResultMapResultDetail>;
3205
+ /**
3206
+ * Gets a read-only version of this map.
3207
+ */
3208
+ toReadOnly(): IReadOnlyValidatingResultMap<TK, TV>;
3209
+ }
2730
3210
 
2731
3211
  declare namespace Validation {
2732
3212
  export {
@@ -2741,17 +3221,28 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2741
3221
  ValidatorTraits,
2742
3222
  ValidatorOptions,
2743
3223
  Constraint,
3224
+ ValidationErrorFormatter,
2744
3225
  Validator
2745
3226
  }
2746
3227
  }
2747
3228
  export { Validation }
2748
3229
 
3230
+ /**
3231
+ * Formats an incoming error message and value that failed validation.
3232
+ * @param val - The value that failed validation.
3233
+ * @param message - The default error message, if any.
3234
+ * @param context - Optional validation context.
3235
+ * @returns The formatted error message.
3236
+ * @public
3237
+ */
3238
+ declare type ValidationErrorFormatter<TC = unknown> = (val: unknown, message?: string, context?: TC) => string;
3239
+
2749
3240
  /**
2750
3241
  * In-place validation that a supplied unknown matches some
2751
3242
  * required characteristics (type, values, etc).
2752
3243
  * @public
2753
3244
  */
2754
- export declare interface Validator<T, TC = undefined> {
3245
+ export declare interface Validator<T, TC = unknown> {
2755
3246
  /**
2756
3247
  * {@link Validation.ValidatorTraits | Traits} describing this validation.
2757
3248
  */
@@ -2818,13 +3309,21 @@ declare type LogLevel = 'detail' | 'info' | 'warning' | 'error' | 'silent';
2818
3309
  * @param brand - The brand to be applied.
2819
3310
  */
2820
3311
  withBrand<B extends string>(brand: B): Validator<Brand<T, B>, TC>;
3312
+ /**
3313
+ * Creates a new {@link Validation.Validator | in-place validator} which
3314
+ * is derived from this one but which returns an error message supplied
3315
+ * by the provided formatter if an error occurs.
3316
+ * @param formatter - The error message formatter to be applied.
3317
+ * @returns A new {@link Validation.Validator | Validator}.
3318
+ */
3319
+ withFormattedError(formatter: ValidationErrorFormatter<TC>): Validator<T, TC>;
2821
3320
  }
2822
3321
 
2823
3322
  /**
2824
3323
  * Abstract base helper class for specific validator implementations
2825
3324
  * @internal
2826
3325
  */
2827
- declare abstract class ValidatorBase<T, TC = undefined> extends GenericValidator<T, TC> {
3326
+ declare abstract class ValidatorBase<T, TC = unknown> extends GenericValidator<T, TC> {
2828
3327
  /**
2829
3328
  * Inner constructor
2830
3329
  * @param params - Initialization params.