ts-fortress 3.1.0 → 4.0.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/README.md +31 -18
  2. package/dist/entry-point.mjs +3 -0
  3. package/dist/entry-point.mjs.map +1 -1
  4. package/dist/index.mjs +4 -0
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/other-types/index.d.mts +2 -0
  7. package/dist/other-types/index.d.mts.map +1 -1
  8. package/dist/other-types/index.mjs +2 -0
  9. package/dist/other-types/index.mjs.map +1 -1
  10. package/dist/other-types/map.d.mts +7 -0
  11. package/dist/other-types/map.d.mts.map +1 -0
  12. package/dist/other-types/map.mjs +70 -0
  13. package/dist/other-types/map.mjs.map +1 -0
  14. package/dist/other-types/set.d.mts +7 -0
  15. package/dist/other-types/set.d.mts.map +1 -0
  16. package/dist/other-types/set.mjs +55 -0
  17. package/dist/other-types/set.mjs.map +1 -0
  18. package/dist/record/keyof.d.mts +4 -3
  19. package/dist/record/keyof.d.mts.map +1 -1
  20. package/dist/record/keyof.mjs +5 -1
  21. package/dist/record/keyof.mjs.map +1 -1
  22. package/dist/record/omit.d.mts +5 -4
  23. package/dist/record/omit.d.mts.map +1 -1
  24. package/dist/record/omit.mjs +8 -39
  25. package/dist/record/omit.mjs.map +1 -1
  26. package/dist/record/partial.d.mts +13 -4
  27. package/dist/record/partial.d.mts.map +1 -1
  28. package/dist/record/partial.mjs +11 -118
  29. package/dist/record/partial.mjs.map +1 -1
  30. package/dist/record/pick.d.mts +5 -4
  31. package/dist/record/pick.d.mts.map +1 -1
  32. package/dist/record/pick.mjs +8 -39
  33. package/dist/record/pick.mjs.map +1 -1
  34. package/dist/record/record.d.mts +4 -24
  35. package/dist/record/record.d.mts.map +1 -1
  36. package/dist/record/record.mjs +9 -7
  37. package/dist/record/record.mjs.map +1 -1
  38. package/dist/type.d.mts +25 -1
  39. package/dist/type.d.mts.map +1 -1
  40. package/dist/type.mjs +1 -1
  41. package/dist/utils/index.d.mts +1 -0
  42. package/dist/utils/index.d.mts.map +1 -1
  43. package/dist/utils/index.mjs +1 -0
  44. package/dist/utils/index.mjs.map +1 -1
  45. package/dist/utils/to-union-string.d.mts +2 -0
  46. package/dist/utils/to-union-string.d.mts.map +1 -0
  47. package/dist/utils/to-union-string.mjs +4 -0
  48. package/dist/utils/to-union-string.mjs.map +1 -0
  49. package/package.json +6 -6
  50. package/src/other-types/index.mts +2 -0
  51. package/src/other-types/map.mts +99 -0
  52. package/src/other-types/map.test.mts +181 -0
  53. package/src/other-types/set.mts +74 -0
  54. package/src/other-types/set.test.mts +199 -0
  55. package/src/record/keyof.mts +34 -12
  56. package/src/record/omit.mts +37 -70
  57. package/src/record/omit.test.mts +8 -1
  58. package/src/record/partial.mts +165 -156
  59. package/src/record/partial.test.mts +44 -4
  60. package/src/record/pick.mts +37 -73
  61. package/src/record/pick.test.mts +8 -1
  62. package/src/record/record-strict-composition.test.mts +16 -16
  63. package/src/record/record.mts +17 -48
  64. package/src/record/record.test.mts +9 -1
  65. package/src/type.mts +54 -2
  66. package/src/utils/index.mts +1 -0
  67. package/src/utils/to-union-string.mts +2 -0
package/README.md CHANGED
@@ -7,11 +7,12 @@ TypeScript-first schema validation library with static type inference.
7
7
  [![License](https://img.shields.io/npm/l/ts-fortress.svg)](./LICENSE)
8
8
  [![codecov](https://codecov.io/gh/noshiro-pf/ts-fortress/graph/badge.svg?token=Y522SWQTPB)](https://codecov.io/gh/noshiro-pf/ts-fortress)
9
9
 
10
- **ts-fortress** is a runtime validation library similar to [io-ts](https://github.com/gcanti/io-ts) and [zod](https://github.com/colinhacks/zod), designed to provide type-safe schema validation with excellent TypeScript integration and static type inference.
10
+ **ts-fortress** is a runtime validation library similar to [io-ts](https://github.com/gcanti/io-ts) and [zod/mini](https://zod.dev/packages/mini), designed to provide type-safe schema validation with excellent TypeScript integration and static type inference.
11
11
 
12
12
  ## Features
13
13
 
14
14
  - 🔒 **Type-safe validation** - Full TypeScript support with static type inference
15
+ - 📖 **Readonly by default** - All constructed types are fully readonly, preventing accidental mutations and promoting immutability
15
16
  - 🏗️ **Composable schemas** - Build complex validation schemas from simple building blocks
16
17
  - 🔄 **Result-based error handling** - Structured error reporting with `Result<T, readonly ValidationError[]>`
17
18
  - 🏷️ **Branded types** - Rich collection of branded number types (Int, SafeInt, PositiveInt, etc.)
@@ -210,7 +211,7 @@ export const SomeObject = t.record({
210
211
 
211
212
  // ✅ Correct ts-fortress usage - enforced by TypeScript
212
213
  export const SomeObject = t.record({
213
- key1: t.numberLiteral(1), // or t.number(1) with default
214
+ key1: t.literal(1), // or t.number(1) with default
214
215
  key2: t.string(''),
215
216
  });
216
217
  ```
@@ -633,8 +634,8 @@ const nullType = t.nullType;
633
634
  const undefinedType = t.undefinedType;
634
635
 
635
636
  // Literal types
636
- const statusType = t.stringLiteral('active');
637
- const versionType = t.number(1);
637
+ const statusType = t.literal('active');
638
+ const versionType = t.literal(1);
638
639
 
639
640
  // Arrays
640
641
  const stringArrayType = t.array(t.string(''));
@@ -647,6 +648,8 @@ const coordinateType = t.tuple([t.number(0), t.number(0)]);
647
648
  ### Record Types
648
649
 
649
650
  ```typescript
651
+ import * as t from 'ts-fortress';
652
+
650
653
  // Define object schemas
651
654
  const PersonType = t.record({
652
655
  firstName: t.string(''),
@@ -732,9 +735,11 @@ UserSchema.is({
732
735
  ts-fortress provides extensive support for branded types to create domain-specific validation:
733
736
 
734
737
  ```typescript
738
+ import * as t from 'ts-fortress';
739
+
735
740
  // Simple branded types
736
- const UserId = t.simpleBrandedString('UserId', '');
737
- const Weight = t.simpleBrandedNumber('Weight', 0);
741
+ const UserId = t.simpleBrandedString({ typeName: 'UserId', defaultValue: '' });
742
+ const Weight = t.simpleBrandedNumber({ typeName: 'Weight', defaultValue: 0 });
738
743
 
739
744
  type UserId = t.TypeOf<typeof UserId>; // Brand<string, 'UserId'>
740
745
  type Weight = t.TypeOf<typeof Weight>; // Brand<number, 'Weight'>
@@ -754,14 +759,9 @@ if (t.Result.isOk(userIdResult)) {
754
759
  ### Union and Intersection Types
755
760
 
756
761
  ```typescript
757
- // Union types
758
- const StatusType = t.union([
759
- t.stringLiteral('pending'),
760
- t.stringLiteral('completed'),
761
- t.stringLiteral('failed'),
762
- ]);
762
+ import * as t from 'ts-fortress';
763
763
 
764
- // Complex unions
764
+ // Union types
765
765
  const IdType = t.union([t.string(''), t.number(0)]);
766
766
 
767
767
  // Intersection types
@@ -786,6 +786,8 @@ const ExtendedUserType = t.mergeRecords([
786
786
  ### Enums
787
787
 
788
788
  ```typescript
789
+ import * as t from 'ts-fortress';
790
+
789
791
  // String enums
790
792
  const ColorEnum = t.enumType(['red', 'green', 'blue']);
791
793
  type Color = t.TypeOf<typeof ColorEnum>; // 'red' | 'green' | 'blue'
@@ -804,6 +806,8 @@ type DiceRoll = t.TypeOf<typeof DiceRoll>; // 1 | 2 | 3 | 4 | 5 | 6
804
806
  ts-fortress uses `Result<T, readonly ValidationError[]>` for structured error handling with detailed error information:
805
807
 
806
808
  ```typescript
809
+ import * as t from 'ts-fortress';
810
+
807
811
  const UserType = t.record({
808
812
  name: t.string(''),
809
813
  age: t.number(0),
@@ -882,7 +886,7 @@ type ValidationError = Readonly<{
882
886
  - `t.number(defaultValue)` - Number validation
883
887
  - `t.boolean(defaultValue)` - Boolean validation
884
888
  - `t.nullType` / `t.undefinedType` - Null/undefined validation
885
- - `t.stringLiteral(value)` - Literal string types
889
+ - `t.literal(value)` - Literal types (string, number, or boolean)
886
890
 
887
891
  ### Collections
888
892
 
@@ -909,18 +913,27 @@ type ValidationError = Readonly<{
909
913
  - `t.intersection(types, defaultType)` - Intersection type validation
910
914
  - `t.mergeRecords(recordTypes)` - Merge multiple record types
911
915
 
912
- ### Branded Types
916
+ ### Refinement
913
917
 
914
- - `t.simpleBrandedString(brandName, defaultValue)` - Simple string branding
915
- - `t.simpleBrandedNumber(brandName, defaultValue)` - Simple number branding
918
+ - `t.refine({ baseType, is, defaultValue })` - Refine `baseType` by `is` function
919
+ - `t.simpleBrandedString({ typeName, defaultValue, is? })` - Simple string branding
920
+ - `t.simpleBrandedNumber({ typeName, defaultValue, is? })` - Simple number branding
916
921
  - Number types: `t.int()`, `t.safeInt()`, `t.positiveInt()`, `t.uint16()`, etc.
917
922
 
918
923
  ### Utilities
919
924
 
920
925
  - `t.TypeOf<T>` - Extract TypeScript type from validator
921
926
  - `t.enumType(values)` - Enum validation
922
- - `t.uintRange({ start, end, defaultValue? })` - Integer range validation
927
+ - `t.uintRange({ start, end, defaultValue? })` - Non-negative integer range validation
928
+ - `t.intRange({ start, end, defaultValue? })` - Integer range validation
923
929
  - `t.unknown` - Unknown Type
930
+ - `t.recursion(typeName, definition)` - Define recursive type
931
+
932
+ ### Pre-defined types
933
+
934
+ - `t.int8` / `t.uint8` - Int8 / Uint8
935
+ - `t.JsonValue` / `t.JsonPrimitive` / `t.JsonObject`
936
+ - `t.nullable(T)` - An alias of `t.union([T, t.undefinedType])`
924
937
 
925
938
  ## Contributing
926
939
 
@@ -30,7 +30,9 @@ export { enumType } from './enum/enum.mjs';
30
30
  export { intRange } from './enum/int-range.mjs';
31
31
  export { uintRange } from './enum/uint-range.mjs';
32
32
  export { literal } from './other-types/literal.mjs';
33
+ export { MapType } from './other-types/map.mjs';
33
34
  export { refine } from './other-types/refine.mjs';
35
+ export { SetType } from './other-types/set.mjs';
34
36
  export { unknown } from './other-types/unknown.mjs';
35
37
  export { int8 } from './predefined/int8.mjs';
36
38
  export { JsonObject, JsonPrimitive, JsonValue } from './predefined/json.mjs';
@@ -55,5 +57,6 @@ export { createCastFn } from './utils/create-cast-fn.mjs';
55
57
  export { createIsFn } from './utils/create-is-fn.mjs';
56
58
  export { createPrimitiveType } from './utils/create-primitive-type.mjs';
57
59
  export { createType } from './utils/create-type.mjs';
60
+ export { toUnionString } from './utils/to-union-string.mjs';
58
61
  export { createPrimitiveValidationError, prependIndexToValidationErrors, prependPathToValidationErrors, validationErrorToMessage, validationErrorsToMessages } from './utils/validation-error.mjs';
59
62
  //# sourceMappingURL=entry-point.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"entry-point.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"entry-point.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.mjs CHANGED
@@ -29,7 +29,9 @@ export { enumType } from './enum/enum.mjs';
29
29
  export { intRange } from './enum/int-range.mjs';
30
30
  export { uintRange } from './enum/uint-range.mjs';
31
31
  export { literal } from './other-types/literal.mjs';
32
+ export { MapType } from './other-types/map.mjs';
32
33
  export { refine } from './other-types/refine.mjs';
34
+ export { SetType } from './other-types/set.mjs';
33
35
  export { unknown } from './other-types/unknown.mjs';
34
36
  export { int8 } from './predefined/int8.mjs';
35
37
  export { JsonObject, JsonPrimitive, JsonValue } from './predefined/json.mjs';
@@ -49,10 +51,12 @@ export { isOptionalProperty, optional } from './record/optional.mjs';
49
51
  export { partial } from './record/partial.mjs';
50
52
  export { pick } from './record/pick.mjs';
51
53
  export { record, strictRecord } from './record/record.mjs';
54
+ import 'ts-data-forge';
52
55
  export { createAssertFn } from './utils/create-assert-fn.mjs';
53
56
  export { createCastFn } from './utils/create-cast-fn.mjs';
54
57
  export { createIsFn } from './utils/create-is-fn.mjs';
55
58
  export { createPrimitiveType } from './utils/create-primitive-type.mjs';
56
59
  export { createType } from './utils/create-type.mjs';
60
+ export { toUnionString } from './utils/to-union-string.mjs';
57
61
  export { createPrimitiveValidationError, prependIndexToValidationErrors, prependPathToValidationErrors, validationErrorToMessage, validationErrorsToMessages } from './utils/validation-error.mjs';
58
62
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,6 @@
1
1
  export * from './literal.mjs';
2
+ export * from './map.mjs';
2
3
  export * from './refine.mjs';
4
+ export * from './set.mjs';
3
5
  export * from './unknown.mjs';
4
6
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/other-types/index.mts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/other-types/index.mts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
@@ -1,4 +1,6 @@
1
1
  export { literal } from './literal.mjs';
2
+ export { MapType } from './map.mjs';
2
3
  export { refine } from './refine.mjs';
4
+ export { SetType } from './set.mjs';
3
5
  export { unknown } from './unknown.mjs';
4
6
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,7 @@
1
+ import { type Type, type TypeOf } from '../type.mjs';
2
+ type MapResultType<K extends Type<unknown>, V extends Type<unknown>> = ReadonlyMap<TypeOf<K>, TypeOf<V>>;
3
+ export declare const MapType: <K extends Type<unknown>, V extends Type<unknown>>(keyType: K, valueType: V, options?: Readonly<{
4
+ typeName?: string;
5
+ }>) => Type<MapResultType<K, V>>;
6
+ export {};
7
+ //# sourceMappingURL=map.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.d.mts","sourceRoot":"","sources":["../../src/other-types/map.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAWrD,KAAK,aAAa,CAChB,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,EACvB,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IACrB,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtC,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,EACtE,SAAS,CAAC,EACV,WAAW,CAAC,EACZ,UAAU,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,KACxC,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CA6E1B,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { Result, Arr, unknownToString } from 'ts-data-forge';
2
+ import { createAssertFn } from '../utils/create-assert-fn.mjs';
3
+ import { createCastFn } from '../utils/create-cast-fn.mjs';
4
+ import { createIsFn } from '../utils/create-is-fn.mjs';
5
+ import { createPrimitiveValidationError, prependPathToValidationErrors } from '../utils/validation-error.mjs';
6
+
7
+ const MapType = (keyType, valueType, options) => {
8
+ const typeName = options?.typeName ?? 'Map';
9
+ const defaultValue = new Map();
10
+ const validate = (a) => {
11
+ if (!(a instanceof Map)) {
12
+ return Result.err([
13
+ createPrimitiveValidationError({
14
+ actualValue: a,
15
+ expectedType: 'Map',
16
+ typeName,
17
+ }),
18
+ ]);
19
+ }
20
+ const errors = Arr.generate(function* () {
21
+ for (const [k, v] of a.entries()) {
22
+ {
23
+ const res = keyType.validate(k);
24
+ if (Result.isErr(res)) {
25
+ yield {
26
+ path: [],
27
+ actualValue: k,
28
+ expectedType: typeName,
29
+ message: `The key of the Map is expected to be <${keyType.typeName}>, but got <${typeof k}> type value \`${unknownToString(k)}\``,
30
+ typeName,
31
+ };
32
+ yield* res.value;
33
+ }
34
+ }
35
+ {
36
+ const res = valueType.validate(v);
37
+ if (Result.isErr(res)) {
38
+ yield {
39
+ path: [],
40
+ actualValue: v,
41
+ expectedType: typeName,
42
+ message: `The value of the Map is expected to be <${valueType.typeName}>, but got <${typeof v}> type value \`${unknownToString(v)}\``,
43
+ typeName,
44
+ };
45
+ yield* prependPathToValidationErrors(res.value, unknownToString(k));
46
+ }
47
+ }
48
+ }
49
+ });
50
+ if (errors.length > 0) {
51
+ return Result.err(errors);
52
+ }
53
+ return Result.ok(a);
54
+ };
55
+ const fill = (a) => a instanceof Map
56
+ ? new Map(Array.from(a.entries()).filter(([k, v]) => keyType.is(k) && valueType.is(v)))
57
+ : defaultValue;
58
+ return {
59
+ typeName,
60
+ defaultValue,
61
+ fill,
62
+ validate,
63
+ is: createIsFn(validate),
64
+ assertIs: createAssertFn(validate),
65
+ cast: createCastFn(validate),
66
+ };
67
+ };
68
+
69
+ export { MapType };
70
+ //# sourceMappingURL=map.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.mjs","sources":["../../src/other-types/map.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAiBO,MAAM,OAAO,GAAG,CACrB,OAAU,EACV,SAAY,EACZ,OAAyC,KACZ;AAG7B,IAAA,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,KAAK;AAE3C,IAAA,MAAM,YAAY,GAAM,IAAI,GAAG,EAAE;AAEjC,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;AAC1C,QAAA,IAAI,EAAE,CAAC,YAAY,GAAG,CAAC,EAAE;YACvB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA,8BAA8B,CAAC;AAC7B,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,KAAK;oBACnB,QAAQ;iBACT,CAAC;AACH,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,QAAQ,CAAC,aAAS;AAC/D,YAAA,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAK,CAAmC,CAAC,OAAO,EAAE,EAAE;gBACnE;oBACE,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE/B,oBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;wBACrB,MAAM;AACJ,4BAAA,IAAI,EAAE,EAAE;AACR,4BAAA,WAAW,EAAE,CAAC;AACd,4BAAA,YAAY,EAAE,QAAQ;AACtB,4BAAA,OAAO,EAAE,CAAA,sCAAA,EAAyC,OAAO,CAAC,QAAQ,CAAA,YAAA,EAAe,OAAO,CAAC,CAAA,eAAA,EAAkB,eAAe,CAAC,CAAC,CAAC,CAAA,EAAA,CAAI;4BACjI,QAAQ;yBAC4B;AAEtC,wBAAA,OAAO,GAAG,CAAC,KAAK;oBAClB;gBACF;gBACA;oBACE,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjC,oBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;wBACrB,MAAM;AACJ,4BAAA,IAAI,EAAE,EAAE;AACR,4BAAA,WAAW,EAAE,CAAC;AACd,4BAAA,YAAY,EAAE,QAAQ;AACtB,4BAAA,OAAO,EAAE,CAAA,wCAAA,EAA2C,SAAS,CAAC,QAAQ,CAAA,YAAA,EAAe,OAAO,CAAC,CAAA,eAAA,EAAkB,eAAe,CAAC,CAAC,CAAC,CAAA,EAAA,CAAI;4BACrI,QAAQ;yBAC4B;AAEtC,wBAAA,OAAO,6BAA6B,CAAC,GAAG,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;oBACrE;gBACF;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3B;AAEA,QAAA,OAAO,MAAM,CAAC,EAAE,CAAC,CAAM,CAAC;AAC1B,IAAA,CAAC;IAED,MAAM,IAAI,GAAoB,CAAC,CAAC,KAC9B,CAAC,YAAY;AACX,UAAG,IAAI,GAAG,CACN,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAC5B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAC7C;UAEH,YAAY;IAElB,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,IAAI;QACJ,QAAQ;AACR,QAAA,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;AACxB,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;AAClC,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;KAC7B;AACH;;;;"}
@@ -0,0 +1,7 @@
1
+ import { type Type, type TypeOf } from '../type.mjs';
2
+ type SetResultType<T extends Type<unknown>> = ReadonlySet<TypeOf<T>>;
3
+ export declare const SetType: <T extends Type<unknown>>(elementType: T, options?: Readonly<{
4
+ typeName?: string;
5
+ }>) => Type<SetResultType<T>>;
6
+ export {};
7
+ //# sourceMappingURL=set.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.d.mts","sourceRoot":"","sources":["../../src/other-types/set.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAUrD,KAAK,aAAa,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAErE,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,EAC7C,aAAa,CAAC,EACd,UAAU,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,KACxC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAyDvB,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { Result, Arr, unknownToString } from 'ts-data-forge';
2
+ import { createAssertFn } from '../utils/create-assert-fn.mjs';
3
+ import { createCastFn } from '../utils/create-cast-fn.mjs';
4
+ import { createIsFn } from '../utils/create-is-fn.mjs';
5
+ import { createPrimitiveValidationError } from '../utils/validation-error.mjs';
6
+
7
+ const SetType = (elementType, options) => {
8
+ const typeName = options?.typeName ?? 'Set';
9
+ const defaultValue = new Set();
10
+ const validate = (a) => {
11
+ if (!(a instanceof Set)) {
12
+ return Result.err([
13
+ createPrimitiveValidationError({
14
+ actualValue: a,
15
+ expectedType: 'Set',
16
+ typeName,
17
+ }),
18
+ ]);
19
+ }
20
+ const errors = Arr.generate(function* () {
21
+ for (const element of a.values()) {
22
+ const res = elementType.validate(element);
23
+ if (Result.isErr(res)) {
24
+ yield {
25
+ path: [],
26
+ actualValue: element,
27
+ expectedType: typeName,
28
+ message: `The element of the Set is expected to be <${elementType.typeName}>, but got <${typeof element}> type value \`${unknownToString(element)}\``,
29
+ typeName,
30
+ };
31
+ yield* res.value;
32
+ }
33
+ }
34
+ });
35
+ if (errors.length > 0) {
36
+ return Result.err(errors);
37
+ }
38
+ return Result.ok(a);
39
+ };
40
+ const fill = (a) => a instanceof Set
41
+ ? new Set(Array.from(a.values()).filter((v) => elementType.is(v)))
42
+ : defaultValue;
43
+ return {
44
+ typeName,
45
+ defaultValue,
46
+ fill,
47
+ validate,
48
+ is: createIsFn(validate),
49
+ assertIs: createAssertFn(validate),
50
+ cast: createCastFn(validate),
51
+ };
52
+ };
53
+
54
+ export { SetType };
55
+ //# sourceMappingURL=set.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.mjs","sources":["../../src/other-types/set.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;MAaa,OAAO,GAAG,CACrB,WAAc,EACd,OAAyC,KACf;AAG1B,IAAA,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,KAAK;AAE3C,IAAA,MAAM,YAAY,GAAM,IAAI,GAAG,EAAE;AAEjC,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;AAC1C,QAAA,IAAI,EAAE,CAAC,YAAY,GAAG,CAAC,EAAE;YACvB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA,8BAA8B,CAAC;AAC7B,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,KAAK;oBACnB,QAAQ;iBACT,CAAC;AACH,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,MAAM,GAA+B,GAAG,CAAC,QAAQ,CAAC,aAAS;YAC/D,KAAK,MAAM,OAAO,IAAK,CAA0B,CAAC,MAAM,EAAE,EAAE;gBAC1D,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;AAEzC,gBAAA,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;oBACrB,MAAM;AACJ,wBAAA,IAAI,EAAE,EAAE;AACR,wBAAA,WAAW,EAAE,OAAO;AACpB,wBAAA,YAAY,EAAE,QAAQ;AACtB,wBAAA,OAAO,EAAE,CAAA,0CAAA,EAA6C,WAAW,CAAC,QAAQ,CAAA,YAAA,EAAe,OAAO,OAAO,CAAA,eAAA,EAAkB,eAAe,CAAC,OAAO,CAAC,CAAA,EAAA,CAAI;wBACrJ,QAAQ;qBAC4B;AAEtC,oBAAA,OAAO,GAAG,CAAC,KAAK;gBAClB;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3B;AAEA,QAAA,OAAO,MAAM,CAAC,EAAE,CAAC,CAAM,CAAC;AAC1B,IAAA,CAAC;IAED,MAAM,IAAI,GAAoB,CAAC,CAAC,KAC9B,CAAC,YAAY;AACX,UAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;UAChE,YAAY;IAElB,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,IAAI;QACJ,QAAQ;AACR,QAAA,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;AACxB,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;AAClC,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;KAC7B;AACH;;;;"}
@@ -1,7 +1,8 @@
1
- import { type Type, type TypeOf } from '../type.mjs';
2
- export declare const keyof: <const R extends Type<UnknownRecord>>(recordType: R, options?: Partial<Readonly<{
1
+ import { type RecordType, type Type } from '../type.mjs';
2
+ export declare const keyof: <const R extends ReadonlyRecord<string, Type<unknown>>>(recordType: RecordType<R>, options?: Partial<Readonly<{
3
3
  typeName: string;
4
4
  }>>) => KeyofType<R>;
5
- type KeyofType<R extends Type<UnknownRecord>> = Type<ToString<keyof TypeOf<R>>>;
5
+ type KeyofTypeSub<R extends ReadonlyRecord<string, Type<unknown>>> = Type<ToString<keyof R>>;
6
+ type KeyofType<R extends ReadonlyRecord<string, Type<unknown>>> = IsNever<keyof R> extends true ? Type<undefined> : KeyofTypeSub<R>;
6
7
  export {};
7
8
  //# sourceMappingURL=keyof.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyof.d.mts","sourceRoot":"","sources":["../../src/record/keyof.mts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAErD,eAAO,MAAM,KAAK,GAAI,KAAK,CAAC,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,EACvD,YAAY,CAAC,EACb,UAAU,OAAO,CACf,QAAQ,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CACH,KACA,SAAS,CAAC,CAAC,CAQW,CAAC;AAE1B,KAAK,SAAS,CAAC,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"keyof.d.mts","sourceRoot":"","sources":["../../src/record/keyof.mts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAEzD,eAAO,MAAM,KAAK,GAAI,KAAK,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EACzE,YAAY,UAAU,CAAC,CAAC,CAAC,EACzB,UAAU,OAAO,CACf,QAAQ,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CACH,KACA,SAAS,CAAC,CAAC,CAQW,CAAC;AAQ1B,KAAK,YAAY,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CACvE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAClB,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,IAC5D,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC"}
@@ -4,11 +4,15 @@ import { undefinedType } from '../primitives/undefined.mjs';
4
4
 
5
5
  const keyof = (recordType, options) =>
6
6
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
7
- pipe(Object.keys(recordType.defaultValue)).map((keys) => Arr.isNonEmpty(keys)
7
+ pipe(getKeys(recordType)).map((keys) => Arr.isNonEmpty(keys)
8
8
  ? enumType(keys, {
9
9
  typeName: options?.typeName ?? `keyof ${recordType.typeName}`,
10
10
  })
11
11
  : undefinedType).value;
12
+ const getKeys = (recordType) =>
13
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
14
+ Object.keys(recordType.shape);
15
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
12
16
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
13
17
 
14
18
  export { keyof };
@@ -1 +1 @@
1
- {"version":3,"file":"keyof.mjs","sources":["../../src/record/keyof.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;MAKa,KAAK,GAAG,CACnB,UAAa,EACb,OAIC;AAED;AACA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAClD,GAAG,CAAC,UAAU,CAAC,IAAI;AACjB,MAAE,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAA,MAAA,EAAS,UAAU,CAAC,QAAQ,CAAA,CAAE;KAC9D;AACH,MAAE,aAAa,CAClB,CAAC;AAIJ;;;;"}
1
+ {"version":3,"file":"keyof.mjs","sources":["../../src/record/keyof.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;MAKa,KAAK,GAAG,CACnB,UAAyB,EACzB,OAIC;AAED;AACA,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KACjC,GAAG,CAAC,UAAU,CAAC,IAAI;AACjB,MAAG,QAAQ,CAAC,IAAI,EAAE;QACd,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAA,MAAA,EAAS,UAAU,CAAC,QAAQ,CAAA,CAAE;KAC9D;AACH,MAAG,aAAwC,CAC9C,CAAC;AAEJ,MAAM,OAAO,GAAG,CACd,UAAyB;AAEzB;AACA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAA2C;AASzE;AAIA;;;;"}
@@ -1,8 +1,9 @@
1
- import { type Type, type TypeOf } from '../type.mjs';
1
+ import { type RecordType, type Type } from '../type.mjs';
2
2
  /** Creates a record type with keys omitted. */
3
- export declare const omit: <const R extends Type<UnknownRecord>, const KeysToOmit extends readonly (keyof TypeOf<R> & string)[]>(recordType: R, keysToOmit: KeysToOmit, options?: Partial<Readonly<{
3
+ export declare const omit: <const R extends ReadonlyRecord<string, Type<unknown>>, const KeysToOmit extends readonly (keyof R & string)[]>(recordType: RecordType<R>, keysToOmit: KeysToOmit, options?: Partial<Readonly<{
4
4
  typeName: string;
5
+ /** @default true */
6
+ allowExcessProperties: boolean;
5
7
  }>>) => OmittedType<R, KeysToOmit>;
6
- type OmittedType<R extends Type<UnknownRecord>, KeysToOmit extends readonly (keyof TypeOf<R>)[]> = Type<Omit<TypeOf<R>, ArrayElement<KeysToOmit>>>;
7
- export {};
8
+ export type OmittedType<R extends ReadonlyRecord<string, Type<unknown>>, KeysToOmit extends readonly (keyof R)[]> = RecordType<Omit<R, ArrayElement<KeysToOmit>>>;
8
9
  //# sourceMappingURL=omit.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"omit.d.mts","sourceRoot":"","sources":["../../src/record/omit.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrD,+CAA+C;AAC/C,eAAO,MAAM,IAAI,GACf,KAAK,CAAC,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,EACnC,KAAK,CAAC,UAAU,SAAS,SAAS,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,EAE9D,YAAY,CAAC,EACb,YAAY,UAAU,EACtB,UAAU,OAAO,CACf,QAAQ,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CACH,KACA,WAAW,CAAC,CAAC,EAAE,UAAU,CA2C3B,CAAC;AAEF,KAAK,WAAW,CACd,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,EAC7B,UAAU,SAAS,SAAS,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,IAC7C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"omit.d.mts","sourceRoot":"","sources":["../../src/record/omit.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAIzD,+CAA+C;AAC/C,eAAO,MAAM,IAAI,GACf,KAAK,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EACrD,KAAK,CAAC,UAAU,SAAS,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,EAEtD,YAAY,UAAU,CAAC,CAAC,CAAC,EACzB,YAAY,UAAU,EACtB,UAAU,OAAO,CACf,QAAQ,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IAEjB,oBAAoB;IACpB,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC,CACH,KACA,WAAW,CAAC,CAAC,EAAE,UAAU,CAOxB,CAAC;AAEL,MAAM,MAAM,WAAW,CACrB,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAC/C,UAAU,SAAS,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,IACrC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC"}
@@ -1,44 +1,13 @@
1
- import { Obj, isRecord, Result } from 'ts-data-forge';
2
- import { createAssertFn } from '../utils/create-assert-fn.mjs';
3
- import { createCastFn } from '../utils/create-cast-fn.mjs';
4
- import { createIsFn } from '../utils/create-is-fn.mjs';
5
- import { createPrimitiveValidationError } from '../utils/validation-error.mjs';
1
+ import { Obj } from 'ts-data-forge';
2
+ import { toUnionString } from '../utils/to-union-string.mjs';
3
+ import { record } from './record.mjs';
6
4
 
7
5
  /** Creates a record type with keys omitted. */
8
- const omit = (recordType, keysToOmit, options) => {
9
- const typeNameFilled = options?.typeName ??
10
- `Omit<${recordType.typeName}, ${keysToOmit.join('|')}>`;
11
- const defaultValue = Obj.omit(recordType.defaultValue, keysToOmit);
12
- const validate = (a) => {
13
- if (!isRecord(a)) {
14
- return Result.err([
15
- createPrimitiveValidationError({
16
- actualValue: a,
17
- expectedType: 'record',
18
- typeName: typeNameFilled,
19
- }),
20
- ]);
21
- }
22
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
23
- const objectFilled = {
24
- ...Obj.pick(recordType.fill(a), keysToOmit),
25
- ...a,
26
- };
27
- const baseValidationResult = recordType.validate(objectFilled);
28
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
29
- return Result.map(baseValidationResult, () => a);
30
- };
31
- const fill = (a) => Obj.omit(recordType.fill(a), keysToOmit);
32
- return {
33
- typeName: typeNameFilled,
34
- defaultValue,
35
- fill,
36
- validate,
37
- is: createIsFn(validate),
38
- assertIs: createAssertFn(validate),
39
- cast: createCastFn(validate),
40
- };
41
- };
6
+ const omit = (recordType, keysToOmit, options) => record(Obj.omit(recordType.shape, keysToOmit), {
7
+ typeName: options?.typeName ??
8
+ `Omit<${recordType.typeName}, ${toUnionString(keysToOmit)}>`,
9
+ allowExcessProperties: options?.allowExcessProperties ?? recordType.allowExcessProperties,
10
+ });
42
11
 
43
12
  export { omit };
44
13
  //# sourceMappingURL=omit.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"omit.mjs","sources":["../../src/record/omit.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AASA;AACO,MAAM,IAAI,GAAG,CAIlB,UAAa,EACb,UAAsB,EACtB,OAIC,KAC6B;AAG9B,IAAA,MAAM,cAAc,GAClB,OAAO,EAAE,QAAQ;QACjB,CAAA,KAAA,EAAQ,UAAU,CAAC,QAAQ,CAAA,EAAA,EAAK,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,CAAA,CAAG;AAEzD,IAAA,MAAM,YAAY,GAAM,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC;AAErE,IAAA,MAAM,QAAQ,GAAwB,CAAC,CAAC,KAAI;AAC1C,QAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;YAChB,OAAO,MAAM,CAAC,GAAG,CAAC;AAChB,gBAAA,8BAA8B,CAAC;AAC7B,oBAAA,WAAW,EAAE,CAAC;AACd,oBAAA,YAAY,EAAE,QAAQ;AACtB,oBAAA,QAAQ,EAAE,cAAc;iBACzB,CAAC;AACH,aAAA,CAAC;;;AAIJ,QAAA,MAAM,YAAY,GAAG;AACnB,YAAA,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;AAC3C,YAAA,GAAG,CAAC;SACQ;QAEd,MAAM,oBAAoB,GAAG,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC;;QAG9D,OAAO,MAAM,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAM,CAAC;AACvD,IAAA,CAAC;IAED,MAAM,IAAI,GAAoB,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;IAE7E,OAAO;AACL,QAAA,QAAQ,EAAE,cAAc;QACxB,YAAY;QACZ,IAAI;QACJ,QAAQ;AACR,QAAA,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC;AACxB,QAAA,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;AAClC,QAAA,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;KAC7B;AACH;;;;"}
1
+ {"version":3,"file":"omit.mjs","sources":["../../src/record/omit.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAKA;AACO,MAAM,IAAI,GAAG,CAIlB,UAAyB,EACzB,UAAsB,EACtB,OAOC,KAED,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE;IAC7C,QAAQ,EACN,OAAO,EAAE,QAAQ;QACjB,CAAA,KAAA,EAAQ,UAAU,CAAC,QAAQ,CAAA,EAAA,EAAK,aAAa,CAAC,UAAU,CAAC,CAAA,CAAA,CAAG;AAC9D,IAAA,qBAAqB,EACnB,OAAO,EAAE,qBAAqB,IAAI,UAAU,CAAC,qBAAqB;AACrE,CAAA;;;;"}
@@ -1,13 +1,22 @@
1
- import { type Type, type TypeOf } from '../type.mjs';
1
+ import { type RecordType, type Type } from '../type.mjs';
2
+ import { type OptionalPropertyType } from './optional.mjs';
2
3
  /**
3
4
  * Creates a Partial type. If keysToBeOptional is set, only those keys are
4
5
  * optional, otherwise, all properties are optional.
5
6
  */
6
- export declare const partial: <const R extends Type<UnknownRecord>, const KeysToBeOptional extends NonEmptyArray<keyof TypeOf<R> & string>>(recordType: R, options?: Partial<Readonly<{
7
+ export declare const partial: <const R extends ReadonlyRecord<string, Type<unknown>>, const KeysToBeOptional extends NonEmptyArray<keyof R & string>>(recordType: RecordType<R>, options?: Partial<Readonly<{
7
8
  keysToBeOptional: KeysToBeOptional;
8
9
  typeName: string;
10
+ /** @default true */
11
+ allowExcessProperties: boolean;
9
12
  }>>) => PartialType<R, KeysToBeOptional>;
10
- type PartialTypeValue<R extends Type<UnknownRecord>, KeysToBeOptional extends NonEmptyArray<keyof TypeOf<R> & string> | undefined> = TypeEq<KeysToBeOptional, undefined> extends true ? Partial<TypeOf<R>> : PartiallyPartial<TypeOf<R>, ArrayElement<KeysToBeOptional>>;
11
- type PartialType<R extends Type<UnknownRecord>, KeysToBeOptional extends NonEmptyArray<keyof TypeOf<R> & string> | undefined> = Type<PartialTypeValue<R, KeysToBeOptional>>;
13
+ type PartialTypeShape<R extends ReadonlyRecord<string, Type<unknown>>, KeysToBeOptional extends NonEmptyArray<keyof R & string> | undefined> = TypeEq<KeysToBeOptional, undefined> extends true ? FullyOptionalType<R> : PartiallyOptionalType<R, ArrayElement<KeysToBeOptional>>;
14
+ type FullyOptionalType<R extends ReadonlyRecord<string, Type<unknown>>> = {
15
+ readonly [P in keyof R]: OptionalPropertyType<R[P]>;
16
+ };
17
+ type PartiallyOptionalType<R extends ReadonlyRecord<string, Type<unknown>>, K extends keyof R> = {
18
+ readonly [P in keyof R]: P extends K ? OptionalPropertyType<R[P]> : R[P];
19
+ };
20
+ export type PartialType<R extends ReadonlyRecord<string, Type<unknown>>, KeysToBeOptional extends NonEmptyArray<keyof R & string> | undefined> = RecordType<PartialTypeShape<R, KeysToBeOptional>>;
12
21
  export {};
13
22
  //# sourceMappingURL=partial.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"partial.d.mts","sourceRoot":"","sources":["../../src/record/partial.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrD;;;GAGG;AACH,eAAO,MAAM,OAAO,GAClB,KAAK,CAAC,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,EACnC,KAAK,CAAC,gBAAgB,SAAS,aAAa,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,EAEtE,YAAY,CAAC,EACb,UAAU,OAAO,CACf,QAAQ,CAAC;IACP,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CACH,KACA,WAAW,CAAC,CAAC,EAAE,gBAAgB,CAwEjC,CAAC;AAEF,KAAK,gBAAgB,CACnB,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,EAC7B,gBAAgB,SAAS,aAAa,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,IAE5E,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,SAAS,IAAI,GAC5C,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAClB,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAElE,KAAK,WAAW,CACd,CAAC,SAAS,IAAI,CAAC,aAAa,CAAC,EAC7B,gBAAgB,SAAS,aAAa,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,IAC1E,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"partial.d.mts","sourceRoot":"","sources":["../../src/record/partial.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAGrE;;;GAGG;AACH,eAAO,MAAM,OAAO,GAClB,KAAK,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EACrD,KAAK,CAAC,gBAAgB,SAAS,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EAE9D,YAAY,UAAU,CAAC,CAAC,CAAC,EACzB,UAAU,OAAO,CACf,QAAQ,CAAC;IACP,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IAEjB,oBAAoB;IACpB,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC,CACH,KACA,WAAW,CAAC,CAAC,EAAE,gBAAgB,CA2BjC,CAAC;AAEF,KAAK,gBAAgB,CACnB,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAC/C,gBAAgB,SAAS,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,IAEpE,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,SAAS,IAAI,GAC5C,iBAAiB,CAAC,CAAC,CAAC,GACpB,qBAAqB,CAAC,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAE/D,KAAK,iBAAiB,CAAC,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI;IACxE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACpD,CAAC;AAEF,KAAK,qBAAqB,CACxB,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAC/C,CAAC,SAAS,MAAM,CAAC,IACf;IACF,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACzE,CAAC;AAEF,MAAM,MAAM,WAAW,CACrB,CAAC,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAC/C,gBAAgB,SAAS,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,IAClE,UAAU,CAAC,gBAAgB,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC"}