schematox 1.2.1 → 1.2.2-alpha

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 (63) hide show
  1. package/dist/constants.d.ts +20 -0
  2. package/dist/constants.d.ts.map +1 -0
  3. package/dist/constants.js +22 -0
  4. package/dist/constants.js.map +1 -0
  5. package/dist/index.d.ts +10 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +9 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/parse.d.ts +5 -0
  10. package/dist/parse.d.ts.map +1 -0
  11. package/dist/parse.js +328 -0
  12. package/dist/parse.js.map +1 -0
  13. package/dist/struct.d.ts +48 -0
  14. package/dist/struct.d.ts.map +1 -0
  15. package/dist/struct.js +111 -0
  16. package/dist/struct.js.map +1 -0
  17. package/dist/types/extensions.d.ts +13 -0
  18. package/dist/types/extensions.d.ts.map +1 -0
  19. package/dist/types/extensions.js +2 -0
  20. package/dist/types/extensions.js.map +1 -0
  21. package/dist/types/infer.d.ts +35 -0
  22. package/dist/types/infer.d.ts.map +1 -0
  23. package/dist/types/infer.js +2 -0
  24. package/dist/types/infer.js.map +1 -0
  25. package/dist/types/schema.d.ts +93 -0
  26. package/dist/types/schema.d.ts.map +1 -0
  27. package/dist/types/schema.js +2 -0
  28. package/dist/types/schema.js.map +1 -0
  29. package/dist/types/standard-schema.d.ts +35 -0
  30. package/dist/types/standard-schema.d.ts.map +1 -0
  31. package/dist/types/standard-schema.js +2 -0
  32. package/dist/types/standard-schema.js.map +1 -0
  33. package/dist/types/struct.d.ts +52 -0
  34. package/dist/types/struct.d.ts.map +1 -0
  35. package/dist/types/struct.js +2 -0
  36. package/dist/types/struct.js.map +1 -0
  37. package/dist/types/utils.d.ts +41 -0
  38. package/dist/types/utils.d.ts.map +1 -0
  39. package/dist/types/utils.js +2 -0
  40. package/dist/types/utils.js.map +1 -0
  41. package/dist/utils.d.ts +9 -0
  42. package/dist/utils.d.ts.map +1 -0
  43. package/dist/utils.js +14 -0
  44. package/dist/utils.js.map +1 -0
  45. package/package.json +15 -4
  46. package/src/tests/README.md +390 -0
  47. package/src/tests/by-struct/array.test.ts +1684 -0
  48. package/src/tests/by-struct/boolean.test.ts +741 -0
  49. package/src/tests/by-struct/literal.test.ts +755 -0
  50. package/src/tests/by-struct/number.test.ts +1234 -0
  51. package/src/tests/by-struct/object.test.ts +1484 -0
  52. package/src/tests/by-struct/record.test.ts +1802 -0
  53. package/src/tests/by-struct/string.test.ts +1252 -0
  54. package/src/tests/by-struct/tuple.test.ts +1341 -0
  55. package/src/tests/by-struct/union.test.ts +1284 -0
  56. package/src/tests/fixtures.ts +52 -0
  57. package/src/tests/fold-constants.ts +247 -0
  58. package/src/tests/fold-morph.ts +49 -0
  59. package/src/tests/type.ts +1 -0
  60. package/src/tests/types/extensions.test.ts +117 -0
  61. package/src/tests/types/infer.test.ts +1410 -0
  62. package/src/tests/utils.test.ts +191 -0
  63. package/CHANGELOG.md +0 -52
@@ -0,0 +1,755 @@
1
+ import * as x from '../../'
2
+ import * as fixture from '../fixtures'
3
+
4
+ import type { StructSharedKeys } from '../type'
5
+
6
+ describe('Type inference and parse by schema/construct/struct (foldA)', () => {
7
+ it('required', () => {
8
+ const schema = { type: 'literal', of: 'x' } as const satisfies x.Schema
9
+ const struct = x.literal('x')
10
+
11
+ type ExpectedSubj = 'x'
12
+
13
+ const subjects: Array<ExpectedSubj> = ['x']
14
+
15
+ foldA: {
16
+ const construct = x.makeStruct(schema)
17
+
18
+ /* ensure that schema/construct/struct/~standard subject types are identical */
19
+
20
+ type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
21
+
22
+ x.tCh<ConstructSchemaSubj, ExpectedSubj>()
23
+ x.tCh<ExpectedSubj, ConstructSchemaSubj>()
24
+
25
+ type SchemaSubj = x.Infer<typeof schema>
26
+
27
+ x.tCh<SchemaSubj, ExpectedSubj>()
28
+ x.tCh<ExpectedSubj, SchemaSubj>()
29
+
30
+ type StructSubj = x.Infer<typeof struct.__schema>
31
+
32
+ x.tCh<StructSubj, ExpectedSubj>()
33
+ x.tCh<ExpectedSubj, StructSubj>()
34
+
35
+ type StandardSubj = NonNullable<
36
+ (typeof struct)['~standard']['types']
37
+ >['output']
38
+
39
+ x.tCh<StandardSubj, ExpectedSubj>()
40
+ x.tCh<ExpectedSubj, StandardSubj>()
41
+
42
+ /* parsed either type check */
43
+
44
+ type ExpectedParsed = x.ParseResult<ExpectedSubj>
45
+
46
+ const parsed = x.parse(schema, undefined)
47
+
48
+ type SchemaParsed = typeof parsed
49
+
50
+ x.tCh<SchemaParsed, ExpectedParsed>()
51
+ x.tCh<ExpectedParsed, SchemaParsed>()
52
+
53
+ type ConstructParsed = ReturnType<typeof construct.parse>
54
+
55
+ x.tCh<ConstructParsed, ExpectedParsed>()
56
+ x.tCh<ExpectedParsed, ConstructParsed>()
57
+
58
+ type StructParsed = ReturnType<typeof struct.parse>
59
+
60
+ x.tCh<StructParsed, ExpectedParsed>()
61
+ x.tCh<ExpectedParsed, StructParsed>()
62
+
63
+ type StandardParsed = Extract<
64
+ ReturnType<(typeof struct)['~standard']['validate']>,
65
+ { value: unknown }
66
+ >['value']
67
+
68
+ x.tCh<StandardParsed, ExpectedSubj>()
69
+ x.tCh<ExpectedSubj, StandardParsed>()
70
+
71
+ /* runtime schema check */
72
+
73
+ expect(struct.__schema).toStrictEqual(schema)
74
+ expect(construct.__schema).toStrictEqual(schema)
75
+ expect(construct.__schema === schema).toBe(false)
76
+
77
+ /* parse result check */
78
+
79
+ for (const subj of subjects) {
80
+ const schemaParsed = x.parse(schema, subj)
81
+
82
+ expect(schemaParsed.error).toBe(undefined)
83
+ expect(schemaParsed.data).toStrictEqual(subj)
84
+
85
+ const constructParsed = construct.parse(subj)
86
+
87
+ expect(constructParsed.error).toBe(undefined)
88
+ expect(constructParsed.data).toStrictEqual(subj)
89
+
90
+ const structParsed = struct.parse(subj)
91
+
92
+ expect(structParsed.error).toBe(undefined)
93
+ expect(structParsed.data).toStrictEqual(subj)
94
+
95
+ const standardParsed = struct['~standard'].validate(subj)
96
+
97
+ if (standardParsed instanceof Promise) {
98
+ throw Error('Not expected')
99
+ }
100
+
101
+ if (standardParsed.issues !== undefined) {
102
+ throw Error('not expected')
103
+ }
104
+
105
+ expect(standardParsed.value).toStrictEqual(subj)
106
+ }
107
+ }
108
+ })
109
+
110
+ it('optional', () => {
111
+ const schema = {
112
+ type: 'literal',
113
+ of: 0,
114
+ optional: true,
115
+ } as const satisfies x.Schema
116
+
117
+ const struct = x.literal(0).optional()
118
+
119
+ type ExpectedSubj = 0 | undefined
120
+
121
+ const subjects: Array<ExpectedSubj> = [0, undefined]
122
+
123
+ foldA: {
124
+ const construct = x.makeStruct(schema)
125
+
126
+ /* ensure that schema/construct/struct/~standard subject types are identical */
127
+
128
+ type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
129
+
130
+ x.tCh<ConstructSchemaSubj, ExpectedSubj>()
131
+ x.tCh<ExpectedSubj, ConstructSchemaSubj>()
132
+
133
+ type SchemaSubj = x.Infer<typeof schema>
134
+
135
+ x.tCh<SchemaSubj, ExpectedSubj>()
136
+ x.tCh<ExpectedSubj, SchemaSubj>()
137
+
138
+ type StructSubj = x.Infer<typeof struct.__schema>
139
+
140
+ x.tCh<StructSubj, ExpectedSubj>()
141
+ x.tCh<ExpectedSubj, StructSubj>()
142
+
143
+ type StandardSubj = NonNullable<
144
+ (typeof struct)['~standard']['types']
145
+ >['output']
146
+
147
+ x.tCh<StandardSubj, ExpectedSubj>()
148
+ x.tCh<ExpectedSubj, StandardSubj>()
149
+
150
+ /* parsed either type check */
151
+
152
+ type ExpectedParsed = x.ParseResult<ExpectedSubj>
153
+
154
+ const parsed = x.parse(schema, undefined)
155
+
156
+ type SchemaParsed = typeof parsed
157
+
158
+ x.tCh<SchemaParsed, ExpectedParsed>()
159
+ x.tCh<ExpectedParsed, SchemaParsed>()
160
+
161
+ type ConstructParsed = ReturnType<typeof construct.parse>
162
+
163
+ x.tCh<ConstructParsed, ExpectedParsed>()
164
+ x.tCh<ExpectedParsed, ConstructParsed>()
165
+
166
+ type StructParsed = ReturnType<typeof struct.parse>
167
+
168
+ x.tCh<StructParsed, ExpectedParsed>()
169
+ x.tCh<ExpectedParsed, StructParsed>()
170
+
171
+ type StandardParsed = Extract<
172
+ ReturnType<(typeof struct)['~standard']['validate']>,
173
+ { value: unknown }
174
+ >['value']
175
+
176
+ x.tCh<StandardParsed, ExpectedSubj>()
177
+ x.tCh<ExpectedSubj, StandardParsed>()
178
+
179
+ /* runtime schema check */
180
+
181
+ expect(struct.__schema).toStrictEqual(schema)
182
+ expect(construct.__schema).toStrictEqual(schema)
183
+ expect(construct.__schema === schema).toBe(false)
184
+
185
+ /* parse result check */
186
+
187
+ for (const subj of subjects) {
188
+ const schemaParsed = x.parse(schema, subj)
189
+
190
+ expect(schemaParsed.error).toBe(undefined)
191
+ expect(schemaParsed.data).toStrictEqual(subj)
192
+
193
+ const constructParsed = construct.parse(subj)
194
+
195
+ expect(constructParsed.error).toBe(undefined)
196
+ expect(constructParsed.data).toStrictEqual(subj)
197
+
198
+ const structParsed = struct.parse(subj)
199
+
200
+ expect(structParsed.error).toBe(undefined)
201
+ expect(structParsed.data).toStrictEqual(subj)
202
+
203
+ const standardParsed = struct['~standard'].validate(subj)
204
+
205
+ if (standardParsed instanceof Promise) {
206
+ throw Error('Not expected')
207
+ }
208
+
209
+ if (standardParsed.issues !== undefined) {
210
+ throw Error('not expected')
211
+ }
212
+
213
+ expect(standardParsed.value).toStrictEqual(subj)
214
+ }
215
+ }
216
+ })
217
+
218
+ it('nullable', () => {
219
+ const schema = {
220
+ type: 'literal',
221
+ of: true,
222
+ nullable: true,
223
+ } as const satisfies x.Schema
224
+
225
+ const struct = x.literal(true).nullable()
226
+
227
+ type ExpectedSubj = true | null
228
+
229
+ const subjects: Array<ExpectedSubj> = [true, null]
230
+
231
+ foldA: {
232
+ const construct = x.makeStruct(schema)
233
+
234
+ /* ensure that schema/construct/struct/~standard subject types are identical */
235
+
236
+ type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
237
+
238
+ x.tCh<ConstructSchemaSubj, ExpectedSubj>()
239
+ x.tCh<ExpectedSubj, ConstructSchemaSubj>()
240
+
241
+ type SchemaSubj = x.Infer<typeof schema>
242
+
243
+ x.tCh<SchemaSubj, ExpectedSubj>()
244
+ x.tCh<ExpectedSubj, SchemaSubj>()
245
+
246
+ type StructSubj = x.Infer<typeof struct.__schema>
247
+
248
+ x.tCh<StructSubj, ExpectedSubj>()
249
+ x.tCh<ExpectedSubj, StructSubj>()
250
+
251
+ type StandardSubj = NonNullable<
252
+ (typeof struct)['~standard']['types']
253
+ >['output']
254
+
255
+ x.tCh<StandardSubj, ExpectedSubj>()
256
+ x.tCh<ExpectedSubj, StandardSubj>()
257
+
258
+ /* parsed either type check */
259
+
260
+ type ExpectedParsed = x.ParseResult<ExpectedSubj>
261
+
262
+ const parsed = x.parse(schema, undefined)
263
+
264
+ type SchemaParsed = typeof parsed
265
+
266
+ x.tCh<SchemaParsed, ExpectedParsed>()
267
+ x.tCh<ExpectedParsed, SchemaParsed>()
268
+
269
+ type ConstructParsed = ReturnType<typeof construct.parse>
270
+
271
+ x.tCh<ConstructParsed, ExpectedParsed>()
272
+ x.tCh<ExpectedParsed, ConstructParsed>()
273
+
274
+ type StructParsed = ReturnType<typeof struct.parse>
275
+
276
+ x.tCh<StructParsed, ExpectedParsed>()
277
+ x.tCh<ExpectedParsed, StructParsed>()
278
+
279
+ type StandardParsed = Extract<
280
+ ReturnType<(typeof struct)['~standard']['validate']>,
281
+ { value: unknown }
282
+ >['value']
283
+
284
+ x.tCh<StandardParsed, ExpectedSubj>()
285
+ x.tCh<ExpectedSubj, StandardParsed>()
286
+
287
+ /* runtime schema check */
288
+
289
+ expect(struct.__schema).toStrictEqual(schema)
290
+ expect(construct.__schema).toStrictEqual(schema)
291
+ expect(construct.__schema === schema).toBe(false)
292
+
293
+ /* parse result check */
294
+
295
+ for (const subj of subjects) {
296
+ const schemaParsed = x.parse(schema, subj)
297
+
298
+ expect(schemaParsed.error).toBe(undefined)
299
+ expect(schemaParsed.data).toStrictEqual(subj)
300
+
301
+ const constructParsed = construct.parse(subj)
302
+
303
+ expect(constructParsed.error).toBe(undefined)
304
+ expect(constructParsed.data).toStrictEqual(subj)
305
+
306
+ const structParsed = struct.parse(subj)
307
+
308
+ expect(structParsed.error).toBe(undefined)
309
+ expect(structParsed.data).toStrictEqual(subj)
310
+
311
+ const standardParsed = struct['~standard'].validate(subj)
312
+
313
+ if (standardParsed instanceof Promise) {
314
+ throw Error('Not expected')
315
+ }
316
+
317
+ if (standardParsed.issues !== undefined) {
318
+ throw Error('not expected')
319
+ }
320
+
321
+ expect(standardParsed.value).toStrictEqual(subj)
322
+ }
323
+ }
324
+ })
325
+
326
+ it('optional + nullable', () => {
327
+ const schema = {
328
+ type: 'literal',
329
+ of: 2,
330
+ optional: true,
331
+ nullable: true,
332
+ } as const satisfies x.Schema
333
+ const struct = x.literal(2).optional().nullable()
334
+
335
+ type ExpectedSubj = 2 | undefined | null
336
+
337
+ const subjects: Array<ExpectedSubj> = [2, null, undefined]
338
+
339
+ foldA: {
340
+ const construct = x.makeStruct(schema)
341
+
342
+ /* ensure that schema/construct/struct/~standard subject types are identical */
343
+
344
+ type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
345
+
346
+ x.tCh<ConstructSchemaSubj, ExpectedSubj>()
347
+ x.tCh<ExpectedSubj, ConstructSchemaSubj>()
348
+
349
+ type SchemaSubj = x.Infer<typeof schema>
350
+
351
+ x.tCh<SchemaSubj, ExpectedSubj>()
352
+ x.tCh<ExpectedSubj, SchemaSubj>()
353
+
354
+ type StructSubj = x.Infer<typeof struct.__schema>
355
+
356
+ x.tCh<StructSubj, ExpectedSubj>()
357
+ x.tCh<ExpectedSubj, StructSubj>()
358
+
359
+ type StandardSubj = NonNullable<
360
+ (typeof struct)['~standard']['types']
361
+ >['output']
362
+
363
+ x.tCh<StandardSubj, ExpectedSubj>()
364
+ x.tCh<ExpectedSubj, StandardSubj>()
365
+
366
+ /* parsed either type check */
367
+
368
+ type ExpectedParsed = x.ParseResult<ExpectedSubj>
369
+
370
+ const parsed = x.parse(schema, undefined)
371
+
372
+ type SchemaParsed = typeof parsed
373
+
374
+ x.tCh<SchemaParsed, ExpectedParsed>()
375
+ x.tCh<ExpectedParsed, SchemaParsed>()
376
+
377
+ type ConstructParsed = ReturnType<typeof construct.parse>
378
+
379
+ x.tCh<ConstructParsed, ExpectedParsed>()
380
+ x.tCh<ExpectedParsed, ConstructParsed>()
381
+
382
+ type StructParsed = ReturnType<typeof struct.parse>
383
+
384
+ x.tCh<StructParsed, ExpectedParsed>()
385
+ x.tCh<ExpectedParsed, StructParsed>()
386
+
387
+ type StandardParsed = Extract<
388
+ ReturnType<(typeof struct)['~standard']['validate']>,
389
+ { value: unknown }
390
+ >['value']
391
+
392
+ x.tCh<StandardParsed, ExpectedSubj>()
393
+ x.tCh<ExpectedSubj, StandardParsed>()
394
+
395
+ /* runtime schema check */
396
+
397
+ expect(struct.__schema).toStrictEqual(schema)
398
+ expect(construct.__schema).toStrictEqual(schema)
399
+ expect(construct.__schema === schema).toBe(false)
400
+
401
+ /* parse result check */
402
+
403
+ for (const subj of subjects) {
404
+ const schemaParsed = x.parse(schema, subj)
405
+
406
+ expect(schemaParsed.error).toBe(undefined)
407
+ expect(schemaParsed.data).toStrictEqual(subj)
408
+
409
+ const constructParsed = construct.parse(subj)
410
+
411
+ expect(constructParsed.error).toBe(undefined)
412
+ expect(constructParsed.data).toStrictEqual(subj)
413
+
414
+ const structParsed = struct.parse(subj)
415
+
416
+ expect(structParsed.error).toBe(undefined)
417
+ expect(structParsed.data).toStrictEqual(subj)
418
+
419
+ const standardParsed = struct['~standard'].validate(subj)
420
+
421
+ if (standardParsed instanceof Promise) {
422
+ throw Error('Not expected')
423
+ }
424
+
425
+ if (standardParsed.issues !== undefined) {
426
+ throw Error('not expected')
427
+ }
428
+
429
+ expect(standardParsed.value).toStrictEqual(subj)
430
+ }
431
+ }
432
+ })
433
+ })
434
+
435
+ describe('Struct parameter keys reduction and schema immutability (foldB)', () => {
436
+ it('optional', () => {
437
+ const schema = {
438
+ type: 'literal',
439
+ of: 0,
440
+ optional: true,
441
+ } as const satisfies x.Schema
442
+
443
+ const prevStruct = x.literal(0)
444
+ const struct = prevStruct.optional()
445
+
446
+ type ExpectedKeys = StructSharedKeys | 'brand' | 'nullable' | 'description'
447
+
448
+ foldB: {
449
+ const construct = x.makeStruct(schema)
450
+
451
+ /* ensure that struct keys are reduced after application */
452
+
453
+ type StructKeys = keyof typeof struct
454
+
455
+ x.tCh<StructKeys, ExpectedKeys>()
456
+ x.tCh<ExpectedKeys, StructKeys>()
457
+
458
+ type ConstructKeys = keyof typeof construct
459
+
460
+ x.tCh<ConstructKeys, ExpectedKeys>()
461
+ x.tCh<ExpectedKeys, ConstructKeys>()
462
+
463
+ /* ensure that construct/struct schema types are identical */
464
+
465
+ type ExpectedSchema = typeof schema
466
+ type StructSchema = typeof struct.__schema
467
+
468
+ x.tCh<StructSchema, ExpectedSchema>()
469
+ x.tCh<ExpectedSchema, StructSchema>()
470
+
471
+ type ConstructSchema = typeof struct.__schema
472
+
473
+ x.tCh<ConstructSchema, ExpectedSchema>()
474
+ x.tCh<ExpectedSchema, ConstructSchema>()
475
+
476
+ /* runtime schema check */
477
+
478
+ expect(struct.__schema).toStrictEqual(schema)
479
+ expect(construct.__schema).toStrictEqual(schema)
480
+ expect(construct.__schema === schema).toBe(false)
481
+
482
+ /* runtime schema parameter application immutability check */
483
+
484
+ expect(prevStruct.__schema === struct.__schema).toBe(false)
485
+ }
486
+ })
487
+
488
+ it('optional + nullable', () => {
489
+ const schema = {
490
+ type: 'literal',
491
+ of: 0,
492
+ optional: true,
493
+ nullable: true,
494
+ } as const satisfies x.Schema
495
+
496
+ const prevStruct = x.literal(0).optional()
497
+ const struct = prevStruct.nullable()
498
+
499
+ type ExpectedKeys = StructSharedKeys | 'brand' | 'description'
500
+
501
+ foldB: {
502
+ const construct = x.makeStruct(schema)
503
+
504
+ /* ensure that struct keys are reduced after application */
505
+
506
+ type StructKeys = keyof typeof struct
507
+
508
+ x.tCh<StructKeys, ExpectedKeys>()
509
+ x.tCh<ExpectedKeys, StructKeys>()
510
+
511
+ type ConstructKeys = keyof typeof construct
512
+
513
+ x.tCh<ConstructKeys, ExpectedKeys>()
514
+ x.tCh<ExpectedKeys, ConstructKeys>()
515
+
516
+ /* ensure that construct/struct schema types are identical */
517
+
518
+ type ExpectedSchema = typeof schema
519
+ type StructSchema = typeof struct.__schema
520
+
521
+ x.tCh<StructSchema, ExpectedSchema>()
522
+ x.tCh<ExpectedSchema, StructSchema>()
523
+
524
+ type ConstructSchema = typeof struct.__schema
525
+
526
+ x.tCh<ConstructSchema, ExpectedSchema>()
527
+ x.tCh<ExpectedSchema, ConstructSchema>()
528
+
529
+ /* runtime schema check */
530
+
531
+ expect(struct.__schema).toStrictEqual(schema)
532
+ expect(construct.__schema).toStrictEqual(schema)
533
+ expect(construct.__schema === schema).toBe(false)
534
+
535
+ /* runtime schema parameter application immutability check */
536
+
537
+ expect(prevStruct.__schema === struct.__schema).toBe(false)
538
+ }
539
+ })
540
+
541
+ it('optional + nullable + brand', () => {
542
+ const schema = {
543
+ type: 'literal',
544
+ of: 0,
545
+ optional: true,
546
+ nullable: true,
547
+ brand: ['x', 'y'],
548
+ } as const satisfies x.Schema
549
+
550
+ const prevStruct = x.literal(0).optional().nullable()
551
+ const struct = prevStruct.brand('x', 'y')
552
+
553
+ type ExpectedKeys = StructSharedKeys | 'description'
554
+
555
+ foldB: {
556
+ const construct = x.makeStruct(schema)
557
+
558
+ /* ensure that struct keys are reduced after application */
559
+
560
+ type StructKeys = keyof typeof struct
561
+
562
+ x.tCh<StructKeys, ExpectedKeys>()
563
+ x.tCh<ExpectedKeys, StructKeys>()
564
+
565
+ type ConstructKeys = keyof typeof construct
566
+
567
+ x.tCh<ConstructKeys, ExpectedKeys>()
568
+ x.tCh<ExpectedKeys, ConstructKeys>()
569
+
570
+ /* ensure that construct/struct schema types are identical */
571
+
572
+ type ExpectedSchema = typeof schema
573
+ type StructSchema = typeof struct.__schema
574
+
575
+ x.tCh<StructSchema, ExpectedSchema>()
576
+ x.tCh<ExpectedSchema, StructSchema>()
577
+
578
+ type ConstructSchema = typeof struct.__schema
579
+
580
+ x.tCh<ConstructSchema, ExpectedSchema>()
581
+ x.tCh<ExpectedSchema, ConstructSchema>()
582
+
583
+ /* runtime schema check */
584
+
585
+ expect(struct.__schema).toStrictEqual(schema)
586
+ expect(construct.__schema).toStrictEqual(schema)
587
+ expect(construct.__schema === schema).toBe(false)
588
+
589
+ /* runtime schema parameter application immutability check */
590
+
591
+ expect(prevStruct.__schema === struct.__schema).toBe(false)
592
+ }
593
+ })
594
+
595
+ it('optional + nullable + brand + description', () => {
596
+ const schema = {
597
+ type: 'literal',
598
+ of: 0,
599
+ optional: true,
600
+ nullable: true,
601
+ brand: ['x', 'y'],
602
+ description: 'x',
603
+ } as const satisfies x.Schema
604
+
605
+ const prevStruct = x.literal(0).optional().nullable().brand('x', 'y')
606
+ const struct = prevStruct.description('x')
607
+
608
+ type ExpectedKeys = StructSharedKeys
609
+
610
+ foldB: {
611
+ const construct = x.makeStruct(schema)
612
+
613
+ /* ensure that struct keys are reduced after application */
614
+
615
+ type StructKeys = keyof typeof struct
616
+
617
+ x.tCh<StructKeys, ExpectedKeys>()
618
+ x.tCh<ExpectedKeys, StructKeys>()
619
+
620
+ type ConstructKeys = keyof typeof construct
621
+
622
+ x.tCh<ConstructKeys, ExpectedKeys>()
623
+ x.tCh<ExpectedKeys, ConstructKeys>()
624
+
625
+ /* ensure that construct/struct schema types are identical */
626
+
627
+ type ExpectedSchema = typeof schema
628
+ type StructSchema = typeof struct.__schema
629
+
630
+ x.tCh<StructSchema, ExpectedSchema>()
631
+ x.tCh<ExpectedSchema, StructSchema>()
632
+
633
+ type ConstructSchema = typeof struct.__schema
634
+
635
+ x.tCh<ConstructSchema, ExpectedSchema>()
636
+ x.tCh<ExpectedSchema, ConstructSchema>()
637
+
638
+ /* runtime schema check */
639
+
640
+ expect(struct.__schema).toStrictEqual(schema)
641
+ expect(construct.__schema).toStrictEqual(schema)
642
+ expect(construct.__schema === schema).toBe(false)
643
+
644
+ /* runtime schema parameter application immutability check */
645
+
646
+ expect(prevStruct.__schema === struct.__schema).toBe(false)
647
+ }
648
+ })
649
+
650
+ it('description + brand + nullable + optional', () => {
651
+ const schema = {
652
+ type: 'literal',
653
+ of: 0,
654
+ optional: true,
655
+ nullable: true,
656
+ brand: ['x', 'y'],
657
+ description: 'x',
658
+ } as const satisfies x.Schema
659
+
660
+ const prevStruct = x.literal(0).description('x').brand('x', 'y').nullable()
661
+ const struct = prevStruct.optional()
662
+
663
+ type ExpectedKeys = StructSharedKeys
664
+
665
+ foldB: {
666
+ const construct = x.makeStruct(schema)
667
+
668
+ /* ensure that struct keys are reduced after application */
669
+
670
+ type StructKeys = keyof typeof struct
671
+
672
+ x.tCh<StructKeys, ExpectedKeys>()
673
+ x.tCh<ExpectedKeys, StructKeys>()
674
+
675
+ type ConstructKeys = keyof typeof construct
676
+
677
+ x.tCh<ConstructKeys, ExpectedKeys>()
678
+ x.tCh<ExpectedKeys, ConstructKeys>()
679
+
680
+ /* ensure that construct/struct schema types are identical */
681
+
682
+ type ExpectedSchema = typeof schema
683
+ type StructSchema = typeof struct.__schema
684
+
685
+ x.tCh<StructSchema, ExpectedSchema>()
686
+ x.tCh<ExpectedSchema, StructSchema>()
687
+
688
+ type ConstructSchema = typeof struct.__schema
689
+
690
+ x.tCh<ConstructSchema, ExpectedSchema>()
691
+ x.tCh<ExpectedSchema, ConstructSchema>()
692
+
693
+ /* runtime schema check */
694
+
695
+ expect(struct.__schema).toStrictEqual(schema)
696
+ expect(construct.__schema).toStrictEqual(schema)
697
+ expect(construct.__schema === schema).toBe(false)
698
+
699
+ /* runtime schema parameter application immutability check */
700
+
701
+ expect(prevStruct.__schema === struct.__schema).toBe(false)
702
+ }
703
+ })
704
+ })
705
+
706
+ describe('ERROR_CODE.invalidType (foldC)', () => {
707
+ it('iterate over fixture.DATA_TYPE', () => {
708
+ const schema = {
709
+ type: 'literal',
710
+ of: 'LITERAL_STRING',
711
+ } as const satisfies x.Schema
712
+
713
+ const struct = x.literal(schema.of)
714
+ const source = fixture.DATA_TYPE
715
+
716
+ foldC: {
717
+ const construct = x.makeStruct(schema)
718
+
719
+ for (const [kind, types] of source) {
720
+ if (kind === schema.type) {
721
+ continue
722
+ }
723
+
724
+ for (const subject of types) {
725
+ const expectedError = [
726
+ {
727
+ code: x.ERROR_CODE.invalidType,
728
+ schema: schema,
729
+ subject: subject,
730
+ path: [],
731
+ },
732
+ ]
733
+
734
+ const parsedSchema = x.parse(schema, subject)
735
+ const parsedConstruct = construct.parse(subject)
736
+ const parsedStruct = struct.parse(subject)
737
+
738
+ expect(parsedSchema.error).toStrictEqual(expectedError)
739
+ expect(parsedConstruct.error).toStrictEqual(expectedError)
740
+ expect(parsedStruct.error).toStrictEqual(expectedError)
741
+
742
+ const parsedStandard = struct['~standard'].validate(subject)
743
+
744
+ if (parsedStandard instanceof Promise) {
745
+ throw Error('Not expected')
746
+ }
747
+
748
+ expect(parsedStandard.issues).toStrictEqual([
749
+ { message: x.ERROR_CODE.invalidType, path: [] },
750
+ ])
751
+ }
752
+ }
753
+ }
754
+ })
755
+ })