@strictly/define 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/.eslintrc.cjs +31 -0
  2. package/.out/index.d.ts +20 -0
  3. package/.out/index.js +20 -0
  4. package/.out/transformers/copies/copy.d.ts +4 -0
  5. package/.out/transformers/copies/copy.js +7 -0
  6. package/.out/transformers/copies/copy_to.d.ts +6 -0
  7. package/.out/transformers/copies/copy_to.js +91 -0
  8. package/.out/transformers/copies/mobx_copy.d.ts +5 -0
  9. package/.out/transformers/copies/mobx_copy.js +42 -0
  10. package/.out/transformers/copies/specs/copy_to.tests.d.ts +1 -0
  11. package/.out/transformers/copies/specs/copy_to.tests.js +97 -0
  12. package/.out/transformers/copies/specs/mobx_copy.tests.d.ts +1 -0
  13. package/.out/transformers/copies/specs/mobx_copy.tests.js +19 -0
  14. package/.out/transformers/flatteners/flatten_accessors_of.d.ts +5 -0
  15. package/.out/transformers/flatteners/flatten_accessors_of.js +11 -0
  16. package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.d.ts +3 -0
  17. package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.js +10 -0
  18. package/.out/transformers/flatteners/flatten_type_def_to.d.ts +4 -0
  19. package/.out/transformers/flatteners/flatten_type_def_to.js +49 -0
  20. package/.out/transformers/flatteners/flatten_type_defs_of.d.ts +3 -0
  21. package/.out/transformers/flatteners/flatten_type_defs_of.js +7 -0
  22. package/.out/transformers/flatteners/flatten_value_type_to.d.ts +11 -0
  23. package/.out/transformers/flatteners/flatten_value_type_to.js +79 -0
  24. package/.out/transformers/flatteners/flatten_value_types_of.d.ts +3 -0
  25. package/.out/transformers/flatteners/flatten_value_types_of.js +7 -0
  26. package/.out/transformers/flatteners/json_path.d.ts +2 -0
  27. package/.out/transformers/flatteners/json_path.js +14 -0
  28. package/.out/transformers/flatteners/specs/flatten_accessors_of.tests.d.ts +1 -0
  29. package/.out/transformers/flatteners/specs/flatten_accessors_of.tests.js +90 -0
  30. package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.d.ts +1 -0
  31. package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.js +94 -0
  32. package/.out/transformers/flatteners/specs/flatten_type_def_to.tests.d.ts +1 -0
  33. package/.out/transformers/flatteners/specs/flatten_type_def_to.tests.js +110 -0
  34. package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.d.ts +1 -0
  35. package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.js +17 -0
  36. package/.out/transformers/flatteners/specs/flatten_value_type_to.tests.d.ts +1 -0
  37. package/.out/transformers/flatteners/specs/flatten_value_type_to.tests.js +297 -0
  38. package/.out/transformers/flatteners/specs/flatten_value_types_of.tests.d.ts +1 -0
  39. package/.out/transformers/flatteners/specs/flatten_value_types_of.tests.js +37 -0
  40. package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.d.ts +1 -0
  41. package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.js +167 -0
  42. package/.out/transformers/flatteners/value_path_to_type_path.d.ts +2 -0
  43. package/.out/transformers/flatteners/value_path_to_type_path.js +96 -0
  44. package/.out/tsconfig.json +15 -0
  45. package/.out/tsconfig.tsbuildinfo +1 -0
  46. package/.out/tsup.config.d.ts +3 -0
  47. package/.out/tsup.config.js +12 -0
  48. package/.out/types/builders.d.ts +62 -0
  49. package/.out/types/builders.js +148 -0
  50. package/.out/types/definitions.d.ts +41 -0
  51. package/.out/types/definitions.js +26 -0
  52. package/.out/types/flattened.d.ts +2 -0
  53. package/.out/types/flattened.js +1 -0
  54. package/.out/types/flattened_accessors_of.d.ts +9 -0
  55. package/.out/types/flattened_accessors_of.js +1 -0
  56. package/.out/types/flattened_type_defs_of.d.ts +21 -0
  57. package/.out/types/flattened_type_defs_of.js +1 -0
  58. package/.out/types/flattened_value_types_of.d.ts +6 -0
  59. package/.out/types/flattened_value_types_of.js +1 -0
  60. package/.out/types/json_path_of.d.ts +1 -0
  61. package/.out/types/json_path_of.js +1 -0
  62. package/.out/types/json_paths_of.d.ts +16 -0
  63. package/.out/types/json_paths_of.js +1 -0
  64. package/.out/types/mobx_value_type_of.d.ts +11 -0
  65. package/.out/types/mobx_value_type_of.js +2 -0
  66. package/.out/types/partial_type_def_of.d.ts +40 -0
  67. package/.out/types/partial_type_def_of.js +1 -0
  68. package/.out/types/readonly_type_def_of.d.ts +29 -0
  69. package/.out/types/readonly_type_def_of.js +1 -0
  70. package/.out/types/specs/builder.tests.d.ts +1 -0
  71. package/.out/types/specs/builder.tests.js +93 -0
  72. package/.out/types/specs/flattened_accessors_of.tests.d.ts +1 -0
  73. package/.out/types/specs/flattened_accessors_of.tests.js +11 -0
  74. package/.out/types/specs/flattened_type_defs_of.tests.d.ts +1 -0
  75. package/.out/types/specs/flattened_type_defs_of.tests.js +71 -0
  76. package/.out/types/specs/flattened_value_types_of.tests.d.ts +1 -0
  77. package/.out/types/specs/flattened_value_types_of.tests.js +11 -0
  78. package/.out/types/specs/json_paths_of.tests.d.ts +1 -0
  79. package/.out/types/specs/json_paths_of.tests.js +199 -0
  80. package/.out/types/specs/partial_type_def_of.tests.d.ts +1 -0
  81. package/.out/types/specs/partial_type_def_of.tests.js +50 -0
  82. package/.out/types/specs/readonly_type_def_of.tests.d.ts +1 -0
  83. package/.out/types/specs/readonly_type_def_of.tests.js +55 -0
  84. package/.out/types/specs/strict_definitions.tests.d.ts +1 -0
  85. package/.out/types/specs/strict_definitions.tests.js +42 -0
  86. package/.out/types/specs/value_to_type_paths_of.tests.d.ts +1 -0
  87. package/.out/types/specs/value_to_type_paths_of.tests.js +90 -0
  88. package/.out/types/specs/value_type_of.tests.d.ts +1 -0
  89. package/.out/types/specs/value_type_of.tests.js +91 -0
  90. package/.out/types/specs/value_types_of_discriminated_union.tests.d.ts +1 -0
  91. package/.out/types/specs/value_types_of_discriminated_union.tests.js +9 -0
  92. package/.out/types/strict_definitions.d.ts +44 -0
  93. package/.out/types/strict_definitions.js +1 -0
  94. package/.out/types/value_to_type_paths_of.d.ts +22 -0
  95. package/.out/types/value_to_type_paths_of.js +1 -0
  96. package/.out/types/value_type_of.d.ts +24 -0
  97. package/.out/types/value_type_of.js +1 -0
  98. package/.out/types/value_types_of_discriminated_union.d.ts +9 -0
  99. package/.out/types/value_types_of_discriminated_union.js +1 -0
  100. package/.out/vitest.workspace.d.ts +2 -0
  101. package/.out/vitest.workspace.js +7 -0
  102. package/.turbo/turbo-build.log +18 -0
  103. package/.turbo/turbo-check-types.log +3 -0
  104. package/.turbo/turbo-release$colon$exports.log +3 -0
  105. package/README.md +12 -0
  106. package/dist/index.cjs +798 -0
  107. package/dist/index.d.cts +301 -0
  108. package/dist/index.d.ts +301 -0
  109. package/dist/index.js +775 -0
  110. package/index.ts +20 -0
  111. package/package.exports.json +18 -0
  112. package/package.json +45 -0
  113. package/transformers/copies/copy.ts +18 -0
  114. package/transformers/copies/copy_to.ts +226 -0
  115. package/transformers/copies/mobx_copy.ts +81 -0
  116. package/transformers/copies/specs/copy_to.tests.ts +143 -0
  117. package/transformers/copies/specs/mobx_copy.tests.ts +26 -0
  118. package/transformers/flatteners/flatten_accessors_of.ts +43 -0
  119. package/transformers/flatteners/flatten_json_value_to_type_paths_of.ts +39 -0
  120. package/transformers/flatteners/flatten_type_def_to.ts +127 -0
  121. package/transformers/flatteners/flatten_type_defs_of.ts +16 -0
  122. package/transformers/flatteners/flatten_value_type_to.ts +227 -0
  123. package/transformers/flatteners/flatten_value_types_of.ts +23 -0
  124. package/transformers/flatteners/json_path.ts +15 -0
  125. package/transformers/flatteners/specs/flatten_accessors_of.tests.ts +113 -0
  126. package/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.ts +115 -0
  127. package/transformers/flatteners/specs/flatten_type_def_to.tests.ts +146 -0
  128. package/transformers/flatteners/specs/flatten_type_defs_of.tests.ts +26 -0
  129. package/transformers/flatteners/specs/flatten_value_type_to.tests.ts +452 -0
  130. package/transformers/flatteners/specs/flatten_value_types_of.tests.ts +46 -0
  131. package/transformers/flatteners/specs/value_path_to_type_path.tests.ts +240 -0
  132. package/transformers/flatteners/value_path_to_type_path.ts +164 -0
  133. package/tsconfig.build.json +11 -0
  134. package/tsconfig.json +15 -0
  135. package/tsup.config.ts +16 -0
  136. package/types/builders.ts +284 -0
  137. package/types/definitions.ts +106 -0
  138. package/types/flattened.ts +5 -0
  139. package/types/flattened_accessors_of.ts +15 -0
  140. package/types/flattened_type_defs_of.ts +130 -0
  141. package/types/flattened_value_types_of.ts +11 -0
  142. package/types/json_path_of.ts +7 -0
  143. package/types/json_paths_of.ts +129 -0
  144. package/types/mobx_value_type_of.ts +16 -0
  145. package/types/partial_type_def_of.ts +64 -0
  146. package/types/readonly_type_def_of.ts +53 -0
  147. package/types/specs/builder.tests.ts +295 -0
  148. package/types/specs/flattened_accessors_of.tests.ts +27 -0
  149. package/types/specs/flattened_type_defs_of.tests.ts +212 -0
  150. package/types/specs/flattened_value_types_of.tests.ts +21 -0
  151. package/types/specs/json_paths_of.tests.ts +304 -0
  152. package/types/specs/partial_type_def_of.tests.ts +251 -0
  153. package/types/specs/readonly_type_def_of.tests.ts +158 -0
  154. package/types/specs/strict_definitions.tests.ts +184 -0
  155. package/types/specs/value_to_type_paths_of.tests.ts +181 -0
  156. package/types/specs/value_type_of.tests.ts +329 -0
  157. package/types/specs/value_types_of_discriminated_union.tests.ts +30 -0
  158. package/types/strict_definitions.ts +107 -0
  159. package/types/value_to_type_paths_of.ts +184 -0
  160. package/types/value_type_of.ts +84 -0
  161. package/types/value_types_of_discriminated_union.ts +14 -0
  162. package/vitest.workspace.ts +11 -0
@@ -0,0 +1,16 @@
1
+ import {
2
+ type Type,
3
+ } from './definitions'
4
+ import { type ValueTypeOf } from './value_type_of'
5
+
6
+ const MOBX_OBSERVABLE_KEY = '___mobx_observable'
7
+
8
+ export type MobxObservable<T = {}> = {
9
+ [MOBX_OBSERVABLE_KEY]: true,
10
+ } & T
11
+
12
+ export type NonMobxObservable<T = {}> = {
13
+ [MOBX_OBSERVABLE_KEY]?: never,
14
+ } & T
15
+
16
+ export type MobxValueTypeOf<T extends Type> = ValueTypeOf<T, MobxObservable>
@@ -0,0 +1,64 @@
1
+ import {
2
+ type ListTypeDef,
3
+ type LiteralTypeDef,
4
+ type ObjectTypeDef,
5
+ type RecordTypeDef,
6
+ type Type,
7
+ type TypeDef,
8
+ type TypeDefType,
9
+ type UnionTypeDef,
10
+ } from './definitions'
11
+
12
+ // converts a type def to have nullable values and partial record fields
13
+ export type PartialTypeDefOf<T extends Type> = {
14
+ readonly typeDef: InternalPartialAndNullableOf<T['definition']>,
15
+ }
16
+
17
+ type InternalPartialAndNullableOf<T extends TypeDef> = {
18
+ readonly type: TypeDefType.Union,
19
+ readonly discriminator: null,
20
+ readonly unions: {
21
+ readonly [0]: InternalPartialOf<T>,
22
+ readonly [1]: {
23
+ readonly type: TypeDefType.Literal,
24
+ readonly valuePrototype: [null],
25
+ },
26
+ },
27
+ }
28
+
29
+ type InternalPartialOf<T extends TypeDef> = T extends LiteralTypeDef ? InternalPartialOfLiteral<T>
30
+ : T extends ListTypeDef ? InternalPartialOfList<T>
31
+ : T extends RecordTypeDef ? InternalPartialOfRecord<T>
32
+ : T extends ObjectTypeDef ? InternalPartialOfObject<T>
33
+ : T extends UnionTypeDef ? InternalPartialOfUnion<T>
34
+ : never
35
+
36
+ type InternalPartialOfLiteral<T extends LiteralTypeDef> = T
37
+
38
+ type InternalPartialOfList<T extends ListTypeDef> = {
39
+ readonly type: T['type'],
40
+ readonly elements: InternalPartialAndNullableOf<T['elements']>,
41
+ }
42
+
43
+ type InternalPartialOfRecord<T extends RecordTypeDef> = {
44
+ readonly type: T['type'],
45
+ readonly keyPrototype: T['keyPrototype'],
46
+ readonly valueTypeDef: InternalPartialAndNullableOf<T['valueTypeDef']> | undefined,
47
+ }
48
+
49
+ type InternalPartialOfObject<T extends ObjectTypeDef> = T extends ObjectTypeDef<infer Fields> ? {
50
+ readonly type: T['type'],
51
+ readonly fields: {
52
+ [K in keyof Fields]+?: InternalPartialAndNullableOf<Fields[K]>
53
+ },
54
+ }
55
+ : never
56
+
57
+ type InternalPartialOfUnion<T extends UnionTypeDef> = T extends UnionTypeDef<infer D, infer Unions> ? {
58
+ readonly type: T['type'],
59
+ readonly discriminator: D,
60
+ readonly unions: {
61
+ [K in keyof Unions]: InternalPartialOf<Unions[K]>
62
+ },
63
+ }
64
+ : never
@@ -0,0 +1,53 @@
1
+ import {
2
+ type ListTypeDef,
3
+ type LiteralTypeDef,
4
+ type ObjectTypeDef,
5
+ type RecordTypeDef,
6
+ type Type,
7
+ type TypeDef,
8
+ type UnionTypeDef,
9
+ } from './definitions'
10
+
11
+ export type ReadonlyTypeDefOf<T extends Type> = {
12
+ readonly definition: InternalReadonlyTypeDefOf<T['definition']>,
13
+ }
14
+
15
+ type InternalReadonlyTypeDefOf<T extends TypeDef> = T extends LiteralTypeDef ? InternalReadonlyTypeDefOfLiteral<T>
16
+ : T extends ListTypeDef ? InternalReadonlyTypeDefOfList<T>
17
+ : T extends RecordTypeDef ? InternalReadonlyTypeDefOfRecord<T>
18
+ : T extends ObjectTypeDef ? InternalReadonlyTypeDefOfObject<T>
19
+ : T extends UnionTypeDef ? InternalReadonlyTypeDefOfUnion<T>
20
+ : never
21
+
22
+ type InternalReadonlyTypeDefOfLiteral<T extends LiteralTypeDef> = T
23
+
24
+ type InternalReadonlyTypeDefOfList<T extends ListTypeDef> = {
25
+ readonly type: T['type'],
26
+ readonly elements: InternalReadonlyTypeDefOf<T['elements']>,
27
+ }
28
+
29
+ type InternalReadonlyTypeDefOfRecord<T extends RecordTypeDef> = {
30
+ readonly type: T['type'],
31
+ readonly keyPrototype: T['keyPrototype'],
32
+ readonly valueTypeDef: undefined extends T['valueTypeDef'] ? InternalReadonlyTypeDefOf<
33
+ Exclude<T['valueTypeDef'], undefined>
34
+ > | undefined
35
+ : InternalReadonlyTypeDefOf<T['valueTypeDef']>,
36
+ }
37
+
38
+ type InternalReadonlyTypeDefOfObject<T extends ObjectTypeDef> = T extends ObjectTypeDef<infer Fields> ? {
39
+ readonly type: T['type'],
40
+ readonly fields: {
41
+ readonly [K in keyof Fields]: InternalReadonlyTypeDefOf<Fields[K]>
42
+ },
43
+ }
44
+ : never
45
+
46
+ type InternalReadonlyTypeDefOfUnion<T extends UnionTypeDef> = T extends UnionTypeDef<infer D, infer Unions> ? {
47
+ readonly type: T['type'],
48
+ readonly discriminator: D,
49
+ readonly unions: {
50
+ readonly [K in keyof Unions]: InternalReadonlyTypeDefOf<Unions[K]>
51
+ },
52
+ }
53
+ : never
@@ -0,0 +1,295 @@
1
+ import {
2
+ booleanType,
3
+ list,
4
+ nullable,
5
+ numberType,
6
+ object,
7
+ record,
8
+ stringType,
9
+ union,
10
+ } from 'types/builders'
11
+ import {
12
+ type TypeDefType,
13
+ } from 'types/definitions'
14
+
15
+ describe('builder', function () {
16
+ describe('literal', function () {
17
+ const { definition: typeDef } = numberType
18
+
19
+ it('equals expected type', function () {
20
+ type C = {
21
+ readonly type: TypeDefType.Literal,
22
+ readonly valuePrototype: [number],
23
+ }
24
+
25
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
26
+ })
27
+
28
+ describe('nullable', function () {
29
+ const { definition: typeDef } = nullable(numberType)
30
+
31
+ type C = {
32
+ readonly type: TypeDefType.Union,
33
+ readonly discriminator: null,
34
+ readonly unions: {
35
+ readonly [0]: {
36
+ readonly type: TypeDefType.Literal,
37
+ readonly valuePrototype: [number],
38
+ },
39
+ readonly [1]: {
40
+ readonly type: TypeDefType.Literal,
41
+ readonly valuePrototype: [null],
42
+ },
43
+ },
44
+ }
45
+ it('equals expected type', function () {
46
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
47
+ })
48
+ })
49
+ })
50
+
51
+ describe('list', function () {
52
+ describe('numeric list', function () {
53
+ describe('mutable', function () {
54
+ const { definition: typeDef } = list(numberType)
55
+
56
+ it('equals expected type', function () {
57
+ type C = {
58
+ readonly type: TypeDefType.List,
59
+ elements: {
60
+ readonly type: TypeDefType.Literal,
61
+ readonly valuePrototype: [number],
62
+ },
63
+ }
64
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
65
+ })
66
+ })
67
+ })
68
+
69
+ describe('readonly', function () {
70
+ const { definition: typeDef } = list(numberType).readonly()
71
+
72
+ it('equals expected type', function () {
73
+ type C = {
74
+ readonly type: TypeDefType.List,
75
+ readonly elements: {
76
+ readonly type: TypeDefType.Literal,
77
+ readonly valuePrototype: [number],
78
+ },
79
+ }
80
+
81
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
82
+ })
83
+ })
84
+ })
85
+
86
+ describe('record', function () {
87
+ describe('numeric record', function () {
88
+ describe('mutable', function () {
89
+ const { definition: typeDef } = record<typeof numberType, 'a' | 'b' | 'c'>(numberType)
90
+
91
+ it('equals expected type', function () {
92
+ type C = {
93
+ readonly type: TypeDefType.Record,
94
+ readonly keyPrototype: 'a' | 'b' | 'c',
95
+ valueTypeDef: {
96
+ readonly type: TypeDefType.Literal,
97
+ readonly valuePrototype: [number],
98
+ },
99
+ }
100
+
101
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
102
+ })
103
+ })
104
+
105
+ describe('readonly', function () {
106
+ const { definition: typeDef } = record<typeof numberType, 'a' | 'b' | 'c'>(numberType).readonly()
107
+
108
+ it('equals expected type', function () {
109
+ type C = {
110
+ readonly type: TypeDefType.Record,
111
+ readonly keyPrototype: 'a' | 'b' | 'c',
112
+ readonly valueTypeDef: {
113
+ readonly type: TypeDefType.Literal,
114
+ readonly valuePrototype: [number],
115
+ },
116
+ }
117
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
118
+ })
119
+ })
120
+
121
+ describe('partial', function () {
122
+ const { definition: typeDef } = record<typeof numberType, 'a' | 'b' | 'c'>(numberType).partial()
123
+
124
+ it('equals expected type', function () {
125
+ type C = {
126
+ readonly type: TypeDefType.Record,
127
+ readonly keyPrototype: 'a' | 'b' | 'c',
128
+ valueTypeDef: {
129
+ readonly type: TypeDefType.Literal,
130
+ readonly valuePrototype: [number],
131
+ } | undefined,
132
+ }
133
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
134
+ })
135
+ })
136
+
137
+ describe('partial readonly', function () {
138
+ const { definition: typeDef } = record<typeof numberType, 'a' | 'b' | 'c'>(numberType).partial().readonly()
139
+
140
+ it('equals expected type', function () {
141
+ type C = {
142
+ readonly type: TypeDefType.Record,
143
+ readonly keyPrototype: 'a' | 'b' | 'c',
144
+ readonly valueTypeDef: {
145
+ readonly type: TypeDefType.Literal,
146
+ readonly valuePrototype: [number],
147
+ } | undefined,
148
+ }
149
+
150
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
151
+ })
152
+ })
153
+
154
+ describe('readonly partial', function () {
155
+ const { definition: typeDef } = record<typeof numberType, 'a' | 'b' | 'c'>(numberType).readonly().partial()
156
+
157
+ it('equals expected type', function () {
158
+ type C = {
159
+ readonly type: TypeDefType.Record,
160
+ readonly keyPrototype: 'a' | 'b' | 'c',
161
+ readonly valueTypeDef: {
162
+ readonly type: TypeDefType.Literal,
163
+ readonly valuePrototype: [number],
164
+ } | undefined,
165
+ }
166
+
167
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
168
+ })
169
+ })
170
+ })
171
+ })
172
+
173
+ describe('object', function () {
174
+ const { definition: typeDef } = object()
175
+ .set('a', numberType)
176
+ .setReadonly('b', booleanType)
177
+ .setOptional('c', stringType)
178
+ .setReadonlyOptional('d', numberType)
179
+
180
+ it('equals expected type', function () {
181
+ type C = {
182
+ readonly type: TypeDefType.Object,
183
+ readonly fields:
184
+ & {
185
+ a: {
186
+ readonly type: TypeDefType.Literal,
187
+ readonly valuePrototype: [number],
188
+ },
189
+ }
190
+ & {
191
+ readonly b: {
192
+ readonly type: TypeDefType.Literal,
193
+ readonly valuePrototype: [boolean],
194
+ },
195
+ }
196
+ & {
197
+ c?: {
198
+ readonly type: TypeDefType.Literal,
199
+ readonly valuePrototype: [string],
200
+ },
201
+ }
202
+ & {
203
+ readonly d?: {
204
+ readonly type: TypeDefType.Literal,
205
+ readonly valuePrototype: [number],
206
+ },
207
+ },
208
+ }
209
+
210
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
211
+ })
212
+ })
213
+
214
+ describe('union', function () {
215
+ describe('literals', function () {
216
+ const {
217
+ definition: typeDef,
218
+ } = union()
219
+ .add(
220
+ '1',
221
+ numberType,
222
+ )
223
+ .add(
224
+ '2',
225
+ stringType,
226
+ )
227
+
228
+ it('equals expected type', function () {
229
+ type C = {
230
+ readonly type: TypeDefType.Union,
231
+ readonly discriminator: null,
232
+ readonly unions:
233
+ & {
234
+ readonly [1]: {
235
+ readonly type: TypeDefType.Literal,
236
+ readonly valuePrototype: [number],
237
+ },
238
+ }
239
+ & {
240
+ readonly [2]: {
241
+ readonly type: TypeDefType.Literal,
242
+ readonly valuePrototype: [string],
243
+ },
244
+ },
245
+ }
246
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
247
+ })
248
+ })
249
+
250
+ describe('objects', function () {
251
+ const {
252
+ definition: typeDef,
253
+ } = union()
254
+ .add(
255
+ '1',
256
+ object().set('a', booleanType),
257
+ )
258
+ .add(
259
+ '2',
260
+ object().set('b', numberType),
261
+ )
262
+
263
+ it('equals expected type', function () {
264
+ type C = {
265
+ readonly type: TypeDefType.Union,
266
+ readonly discriminator: null,
267
+ readonly unions:
268
+ & {
269
+ readonly [1]: {
270
+ readonly type: TypeDefType.Object,
271
+ readonly fields: {
272
+ a: {
273
+ readonly type: TypeDefType.Literal,
274
+ readonly valuePrototype: [boolean],
275
+ },
276
+ },
277
+ },
278
+ }
279
+ & {
280
+ readonly [2]: {
281
+ readonly type: TypeDefType.Object,
282
+ readonly fields: {
283
+ b: {
284
+ readonly type: TypeDefType.Literal,
285
+ readonly valuePrototype: [number],
286
+ },
287
+ },
288
+ },
289
+ },
290
+ }
291
+ expectTypeOf(typeDef).toEqualTypeOf<C>()
292
+ })
293
+ })
294
+ })
295
+ })
@@ -0,0 +1,27 @@
1
+ import {
2
+ numberType,
3
+ record,
4
+ } from 'types/builders'
5
+ import { type FlattenedAccessorsOf } from 'types/flattened_accessors_of'
6
+
7
+ describe('FlattenedAccessorsOf', function () {
8
+ // note we only test a small example since most of the work is done in flatten
9
+ describe('record', function () {
10
+ const builder = record<typeof numberType, string>(numberType)
11
+ type V = FlattenedAccessorsOf<typeof builder>
12
+
13
+ let v: {
14
+ readonly $: {
15
+ readonly value: Record<string, number>,
16
+ set: (v: Record<string, number>) => void,
17
+ },
18
+ readonly [_: `$.${string}`]: {
19
+ readonly value: number,
20
+ set: (v: number) => void,
21
+ },
22
+ }
23
+ it('equals expected type', function () {
24
+ expectTypeOf(v).toEqualTypeOf<V>()
25
+ })
26
+ })
27
+ })
@@ -0,0 +1,212 @@
1
+ import { type SimplifyDeep } from 'type-fest'
2
+ import {
3
+ booleanType,
4
+ list,
5
+ numberType,
6
+ object,
7
+ record,
8
+ stringType,
9
+ union,
10
+ } from 'types/builders'
11
+ import { type TypeDefType } from 'types/definitions'
12
+ import { type FlattenedTypeDefsOf } from 'types/flattened_type_defs_of'
13
+
14
+ describe('FlattenedTypeDefsOf', function () {
15
+ describe('literal', function () {
16
+ type T = FlattenedTypeDefsOf<typeof numberType, null>
17
+
18
+ let t: {
19
+ readonly $: {
20
+ readonly definition: {
21
+ readonly type: TypeDefType.Literal,
22
+ readonly valuePrototype: [number],
23
+ },
24
+ },
25
+ }
26
+ it('equals expected type', function () {
27
+ expectTypeOf(t).toEqualTypeOf<T>()
28
+ })
29
+ })
30
+
31
+ describe('list', function () {
32
+ const builder = list(numberType)
33
+ type T = SimplifyDeep<FlattenedTypeDefsOf<typeof builder, '*'>>
34
+
35
+ let t: {
36
+ readonly $: SimplifyDeep<typeof builder.narrow>,
37
+ readonly ['$.*']: {
38
+ readonly definition: {
39
+ readonly type: TypeDefType.Literal,
40
+ readonly valuePrototype: [number],
41
+ },
42
+ },
43
+ }
44
+ it('equals expected type', function () {
45
+ expectTypeOf(t).toEqualTypeOf<T>()
46
+ })
47
+ })
48
+
49
+ describe('record', function () {
50
+ const builder = record<typeof numberType, 'a' | 'b'>(numberType)
51
+ type T = SimplifyDeep<FlattenedTypeDefsOf<typeof builder, '*'>>
52
+
53
+ let t: {
54
+ readonly $: SimplifyDeep<typeof builder.narrow>,
55
+ readonly ['$.*']: {
56
+ readonly definition: {
57
+ readonly type: TypeDefType.Literal,
58
+ readonly valuePrototype: [number],
59
+ },
60
+ },
61
+ }
62
+ it('equals expected type', function () {
63
+ expectTypeOf<typeof t>(t).toEqualTypeOf<T>()
64
+ })
65
+ })
66
+
67
+ describe('object', function () {
68
+ describe('simple', function () {
69
+ const builder = object()
70
+ .set('a', numberType)
71
+ .setOptional('b', stringType)
72
+ .setReadonly('c', booleanType)
73
+ .setReadonlyOptional('d', stringType)
74
+ type T = SimplifyDeep<FlattenedTypeDefsOf<typeof builder, null>>
75
+
76
+ let t: {
77
+ readonly $: SimplifyDeep<typeof builder.narrow>,
78
+ readonly ['$.a']: {
79
+ readonly definition: {
80
+ readonly type: TypeDefType.Literal,
81
+ readonly valuePrototype: [number],
82
+ },
83
+ },
84
+ readonly ['$.b']: {
85
+ readonly definition: {
86
+ readonly type: TypeDefType.Literal,
87
+ readonly valuePrototype: [string],
88
+ },
89
+ },
90
+ readonly ['$.c']: {
91
+ readonly definition: {
92
+ readonly type: TypeDefType.Literal,
93
+ readonly valuePrototype: [boolean],
94
+ },
95
+ },
96
+ readonly ['$.d']: {
97
+ readonly definition: {
98
+ readonly type: TypeDefType.Literal,
99
+ readonly valuePrototype: [string],
100
+ },
101
+ },
102
+ }
103
+ it('equals expected type', function () {
104
+ expectTypeOf(t).toEqualTypeOf<T>()
105
+ })
106
+ })
107
+ })
108
+ })
109
+
110
+ describe('union', function () {
111
+ describe('overlapping', function () {
112
+ describe('non-discriminated', function () {
113
+ const builder = union()
114
+ .add('x', object().set('a', booleanType))
115
+ .add('y', object().set('b', numberType))
116
+ type T = SimplifyDeep<FlattenedTypeDefsOf<typeof builder, null>>
117
+
118
+ let t: {
119
+ readonly $: SimplifyDeep<typeof builder.narrow>,
120
+ readonly ['$.a']: {
121
+ readonly definition: {
122
+ readonly type: TypeDefType.Literal,
123
+ readonly valuePrototype: [boolean],
124
+ },
125
+ },
126
+ readonly ['$.b']: {
127
+ readonly definition: {
128
+ readonly type: TypeDefType.Literal,
129
+ readonly valuePrototype: [number],
130
+ },
131
+ },
132
+ }
133
+
134
+ it('equals expected type', function () {
135
+ expectTypeOf(t).toEqualTypeOf<T>()
136
+ })
137
+ })
138
+
139
+ describe('discriminated', function () {
140
+ const builder = union('x')
141
+ .add('1', object().set('a', booleanType))
142
+ .add('2', object().set('a', numberType))
143
+ type T = SimplifyDeep<FlattenedTypeDefsOf<typeof builder, null>>
144
+
145
+ let t: {
146
+ readonly $: SimplifyDeep<typeof builder.narrow>,
147
+ readonly ['$.1:a']: {
148
+ readonly definition: {
149
+ readonly type: TypeDefType.Literal,
150
+ readonly valuePrototype: [boolean],
151
+ },
152
+ },
153
+ readonly ['$.2:a']: {
154
+ readonly definition: {
155
+ readonly type: TypeDefType.Literal,
156
+ readonly valuePrototype: [number],
157
+ },
158
+ },
159
+ }
160
+ it('equals expected type', function () {
161
+ expectTypeOf(t).toEqualTypeOf<T>()
162
+ })
163
+ })
164
+
165
+ describe('nested discriminated', function () {
166
+ const builder = union('x')
167
+ .add(
168
+ '1',
169
+ union('y')
170
+ .add('p', object().set('a', booleanType))
171
+ .add('q', object().set('a', stringType)),
172
+ )
173
+ .add(
174
+ '2',
175
+ union('z')
176
+ .add('r', object().set('b', numberType))
177
+ .add('s', object().set('c', stringType)),
178
+ )
179
+ type T = SimplifyDeep<FlattenedTypeDefsOf<typeof builder, null>>
180
+ let t: {
181
+ readonly $: SimplifyDeep<typeof builder.narrow>,
182
+ readonly ['$.1:p:a']: {
183
+ readonly definition: {
184
+ readonly type: TypeDefType.Literal,
185
+ readonly valuePrototype: [boolean],
186
+ },
187
+ },
188
+ readonly ['$.1:q:a']: {
189
+ readonly definition: {
190
+ readonly type: TypeDefType.Literal,
191
+ readonly valuePrototype: [string],
192
+ },
193
+ },
194
+ readonly ['$.2:r:b']: {
195
+ readonly definition: {
196
+ readonly type: TypeDefType.Literal,
197
+ readonly valuePrototype: [number],
198
+ },
199
+ },
200
+ readonly ['$.2:s:c']: {
201
+ readonly definition: {
202
+ readonly type: TypeDefType.Literal,
203
+ readonly valuePrototype: [string],
204
+ },
205
+ },
206
+ }
207
+ it('equals expected type', function () {
208
+ expectTypeOf(t).toEqualTypeOf<T>()
209
+ })
210
+ })
211
+ })
212
+ })
@@ -0,0 +1,21 @@
1
+ import {
2
+ numberType,
3
+ record,
4
+ } from 'types/builders'
5
+ import { type FlattenedValueTypesOf } from 'types/flattened_value_types_of'
6
+
7
+ describe('FlattenedValueTypesOf', function () {
8
+ // note we only test a small example since most of the work is done in flatten
9
+ describe('record', function () {
10
+ const builder = record<typeof numberType, string>(numberType)
11
+ type V = FlattenedValueTypesOf<typeof builder>
12
+
13
+ let v: {
14
+ readonly $: Record<string, number>,
15
+ readonly [_: `$.${string}`]: number,
16
+ }
17
+ it('equals expected type', function () {
18
+ expectTypeOf(v).toEqualTypeOf<V>()
19
+ })
20
+ })
21
+ })