@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.
- package/.eslintrc.cjs +31 -0
- package/.out/index.d.ts +20 -0
- package/.out/index.js +20 -0
- package/.out/transformers/copies/copy.d.ts +4 -0
- package/.out/transformers/copies/copy.js +7 -0
- package/.out/transformers/copies/copy_to.d.ts +6 -0
- package/.out/transformers/copies/copy_to.js +91 -0
- package/.out/transformers/copies/mobx_copy.d.ts +5 -0
- package/.out/transformers/copies/mobx_copy.js +42 -0
- package/.out/transformers/copies/specs/copy_to.tests.d.ts +1 -0
- package/.out/transformers/copies/specs/copy_to.tests.js +97 -0
- package/.out/transformers/copies/specs/mobx_copy.tests.d.ts +1 -0
- package/.out/transformers/copies/specs/mobx_copy.tests.js +19 -0
- package/.out/transformers/flatteners/flatten_accessors_of.d.ts +5 -0
- package/.out/transformers/flatteners/flatten_accessors_of.js +11 -0
- package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.d.ts +3 -0
- package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.js +10 -0
- package/.out/transformers/flatteners/flatten_type_def_to.d.ts +4 -0
- package/.out/transformers/flatteners/flatten_type_def_to.js +49 -0
- package/.out/transformers/flatteners/flatten_type_defs_of.d.ts +3 -0
- package/.out/transformers/flatteners/flatten_type_defs_of.js +7 -0
- package/.out/transformers/flatteners/flatten_value_type_to.d.ts +11 -0
- package/.out/transformers/flatteners/flatten_value_type_to.js +79 -0
- package/.out/transformers/flatteners/flatten_value_types_of.d.ts +3 -0
- package/.out/transformers/flatteners/flatten_value_types_of.js +7 -0
- package/.out/transformers/flatteners/json_path.d.ts +2 -0
- package/.out/transformers/flatteners/json_path.js +14 -0
- package/.out/transformers/flatteners/specs/flatten_accessors_of.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_accessors_of.tests.js +90 -0
- package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.js +94 -0
- package/.out/transformers/flatteners/specs/flatten_type_def_to.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_type_def_to.tests.js +110 -0
- package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.js +17 -0
- package/.out/transformers/flatteners/specs/flatten_value_type_to.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_value_type_to.tests.js +297 -0
- package/.out/transformers/flatteners/specs/flatten_value_types_of.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_value_types_of.tests.js +37 -0
- package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.js +167 -0
- package/.out/transformers/flatteners/value_path_to_type_path.d.ts +2 -0
- package/.out/transformers/flatteners/value_path_to_type_path.js +96 -0
- package/.out/tsconfig.json +15 -0
- package/.out/tsconfig.tsbuildinfo +1 -0
- package/.out/tsup.config.d.ts +3 -0
- package/.out/tsup.config.js +12 -0
- package/.out/types/builders.d.ts +62 -0
- package/.out/types/builders.js +148 -0
- package/.out/types/definitions.d.ts +41 -0
- package/.out/types/definitions.js +26 -0
- package/.out/types/flattened.d.ts +2 -0
- package/.out/types/flattened.js +1 -0
- package/.out/types/flattened_accessors_of.d.ts +9 -0
- package/.out/types/flattened_accessors_of.js +1 -0
- package/.out/types/flattened_type_defs_of.d.ts +21 -0
- package/.out/types/flattened_type_defs_of.js +1 -0
- package/.out/types/flattened_value_types_of.d.ts +6 -0
- package/.out/types/flattened_value_types_of.js +1 -0
- package/.out/types/json_path_of.d.ts +1 -0
- package/.out/types/json_path_of.js +1 -0
- package/.out/types/json_paths_of.d.ts +16 -0
- package/.out/types/json_paths_of.js +1 -0
- package/.out/types/mobx_value_type_of.d.ts +11 -0
- package/.out/types/mobx_value_type_of.js +2 -0
- package/.out/types/partial_type_def_of.d.ts +40 -0
- package/.out/types/partial_type_def_of.js +1 -0
- package/.out/types/readonly_type_def_of.d.ts +29 -0
- package/.out/types/readonly_type_def_of.js +1 -0
- package/.out/types/specs/builder.tests.d.ts +1 -0
- package/.out/types/specs/builder.tests.js +93 -0
- package/.out/types/specs/flattened_accessors_of.tests.d.ts +1 -0
- package/.out/types/specs/flattened_accessors_of.tests.js +11 -0
- package/.out/types/specs/flattened_type_defs_of.tests.d.ts +1 -0
- package/.out/types/specs/flattened_type_defs_of.tests.js +71 -0
- package/.out/types/specs/flattened_value_types_of.tests.d.ts +1 -0
- package/.out/types/specs/flattened_value_types_of.tests.js +11 -0
- package/.out/types/specs/json_paths_of.tests.d.ts +1 -0
- package/.out/types/specs/json_paths_of.tests.js +199 -0
- package/.out/types/specs/partial_type_def_of.tests.d.ts +1 -0
- package/.out/types/specs/partial_type_def_of.tests.js +50 -0
- package/.out/types/specs/readonly_type_def_of.tests.d.ts +1 -0
- package/.out/types/specs/readonly_type_def_of.tests.js +55 -0
- package/.out/types/specs/strict_definitions.tests.d.ts +1 -0
- package/.out/types/specs/strict_definitions.tests.js +42 -0
- package/.out/types/specs/value_to_type_paths_of.tests.d.ts +1 -0
- package/.out/types/specs/value_to_type_paths_of.tests.js +90 -0
- package/.out/types/specs/value_type_of.tests.d.ts +1 -0
- package/.out/types/specs/value_type_of.tests.js +91 -0
- package/.out/types/specs/value_types_of_discriminated_union.tests.d.ts +1 -0
- package/.out/types/specs/value_types_of_discriminated_union.tests.js +9 -0
- package/.out/types/strict_definitions.d.ts +44 -0
- package/.out/types/strict_definitions.js +1 -0
- package/.out/types/value_to_type_paths_of.d.ts +22 -0
- package/.out/types/value_to_type_paths_of.js +1 -0
- package/.out/types/value_type_of.d.ts +24 -0
- package/.out/types/value_type_of.js +1 -0
- package/.out/types/value_types_of_discriminated_union.d.ts +9 -0
- package/.out/types/value_types_of_discriminated_union.js +1 -0
- package/.out/vitest.workspace.d.ts +2 -0
- package/.out/vitest.workspace.js +7 -0
- package/.turbo/turbo-build.log +18 -0
- package/.turbo/turbo-check-types.log +3 -0
- package/.turbo/turbo-release$colon$exports.log +3 -0
- package/README.md +12 -0
- package/dist/index.cjs +798 -0
- package/dist/index.d.cts +301 -0
- package/dist/index.d.ts +301 -0
- package/dist/index.js +775 -0
- package/index.ts +20 -0
- package/package.exports.json +18 -0
- package/package.json +45 -0
- package/transformers/copies/copy.ts +18 -0
- package/transformers/copies/copy_to.ts +226 -0
- package/transformers/copies/mobx_copy.ts +81 -0
- package/transformers/copies/specs/copy_to.tests.ts +143 -0
- package/transformers/copies/specs/mobx_copy.tests.ts +26 -0
- package/transformers/flatteners/flatten_accessors_of.ts +43 -0
- package/transformers/flatteners/flatten_json_value_to_type_paths_of.ts +39 -0
- package/transformers/flatteners/flatten_type_def_to.ts +127 -0
- package/transformers/flatteners/flatten_type_defs_of.ts +16 -0
- package/transformers/flatteners/flatten_value_type_to.ts +227 -0
- package/transformers/flatteners/flatten_value_types_of.ts +23 -0
- package/transformers/flatteners/json_path.ts +15 -0
- package/transformers/flatteners/specs/flatten_accessors_of.tests.ts +113 -0
- package/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.ts +115 -0
- package/transformers/flatteners/specs/flatten_type_def_to.tests.ts +146 -0
- package/transformers/flatteners/specs/flatten_type_defs_of.tests.ts +26 -0
- package/transformers/flatteners/specs/flatten_value_type_to.tests.ts +452 -0
- package/transformers/flatteners/specs/flatten_value_types_of.tests.ts +46 -0
- package/transformers/flatteners/specs/value_path_to_type_path.tests.ts +240 -0
- package/transformers/flatteners/value_path_to_type_path.ts +164 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +15 -0
- package/tsup.config.ts +16 -0
- package/types/builders.ts +284 -0
- package/types/definitions.ts +106 -0
- package/types/flattened.ts +5 -0
- package/types/flattened_accessors_of.ts +15 -0
- package/types/flattened_type_defs_of.ts +130 -0
- package/types/flattened_value_types_of.ts +11 -0
- package/types/json_path_of.ts +7 -0
- package/types/json_paths_of.ts +129 -0
- package/types/mobx_value_type_of.ts +16 -0
- package/types/partial_type_def_of.ts +64 -0
- package/types/readonly_type_def_of.ts +53 -0
- package/types/specs/builder.tests.ts +295 -0
- package/types/specs/flattened_accessors_of.tests.ts +27 -0
- package/types/specs/flattened_type_defs_of.tests.ts +212 -0
- package/types/specs/flattened_value_types_of.tests.ts +21 -0
- package/types/specs/json_paths_of.tests.ts +304 -0
- package/types/specs/partial_type_def_of.tests.ts +251 -0
- package/types/specs/readonly_type_def_of.tests.ts +158 -0
- package/types/specs/strict_definitions.tests.ts +184 -0
- package/types/specs/value_to_type_paths_of.tests.ts +181 -0
- package/types/specs/value_type_of.tests.ts +329 -0
- package/types/specs/value_types_of_discriminated_union.tests.ts +30 -0
- package/types/strict_definitions.ts +107 -0
- package/types/value_to_type_paths_of.ts +184 -0
- package/types/value_type_of.ts +84 -0
- package/types/value_types_of_discriminated_union.ts +14 -0
- package/vitest.workspace.ts +11 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type TypeDefType,
|
|
3
|
+
type UnionTypeDef,
|
|
4
|
+
} from 'types/definitions'
|
|
5
|
+
import {
|
|
6
|
+
type IsStrictUnion,
|
|
7
|
+
type StrictUnionTypeDef,
|
|
8
|
+
} from 'types/strict_definitions'
|
|
9
|
+
|
|
10
|
+
describe('Strict Definitions', function () {
|
|
11
|
+
describe('IsStrictUnion', function () {
|
|
12
|
+
it('detects a non-discriminated strict union', function () {
|
|
13
|
+
type U = {
|
|
14
|
+
readonly [1]: {
|
|
15
|
+
type: TypeDefType.Literal,
|
|
16
|
+
valuePrototype: ['a'],
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
type C = IsStrictUnion<U>
|
|
20
|
+
expectTypeOf<C>().toEqualTypeOf<true>()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('detects a union with a non-literal type', function () {
|
|
24
|
+
type U = {
|
|
25
|
+
readonly [1]: {
|
|
26
|
+
type: TypeDefType.List,
|
|
27
|
+
elements: {
|
|
28
|
+
type: TypeDefType.Literal,
|
|
29
|
+
valuePrototype: ['a'],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
type C = IsStrictUnion<U>
|
|
34
|
+
expectTypeOf<C>().toEqualTypeOf<false>()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('detects a union with a non-literal type in position 0', function () {
|
|
38
|
+
type U = {
|
|
39
|
+
readonly [0]: {
|
|
40
|
+
type: TypeDefType.List,
|
|
41
|
+
elements: {
|
|
42
|
+
type: TypeDefType.Literal,
|
|
43
|
+
valuePrototype: ['a'],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
type C = IsStrictUnion<U>
|
|
48
|
+
expectTypeOf<C>().toEqualTypeOf<true>()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('detects a non-discriminated strict union with multiple options and a non-literal type', function () {
|
|
52
|
+
type U = {
|
|
53
|
+
readonly [1]: {
|
|
54
|
+
type: TypeDefType.Literal,
|
|
55
|
+
valuePrototype: ['a'],
|
|
56
|
+
},
|
|
57
|
+
readonly [2]: {
|
|
58
|
+
type: TypeDefType.Literal,
|
|
59
|
+
valuePrototype: ['c'],
|
|
60
|
+
},
|
|
61
|
+
readonly [0]: {
|
|
62
|
+
type: TypeDefType.List,
|
|
63
|
+
elements: {
|
|
64
|
+
type: TypeDefType.Literal,
|
|
65
|
+
valuePrototype: ['a'],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
type C = IsStrictUnion<U>
|
|
70
|
+
expectTypeOf<C>().toEqualTypeOf<true>()
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('StrictUnion', function () {
|
|
75
|
+
it('enforces non-strict unions are of type never', function () {
|
|
76
|
+
type U = {
|
|
77
|
+
readonly [1]: {
|
|
78
|
+
type: TypeDefType.List,
|
|
79
|
+
elements: {
|
|
80
|
+
type: TypeDefType.Literal,
|
|
81
|
+
valuePrototype: ['a'],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
type C = StrictUnionTypeDef<null, U>
|
|
86
|
+
expectTypeOf<C>().toEqualTypeOf<never>()
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('allows unions of multiple literal options', function () {
|
|
90
|
+
type U = {
|
|
91
|
+
readonly [1]: {
|
|
92
|
+
readonly type: TypeDefType.Literal,
|
|
93
|
+
readonly valuePrototype: ['a'],
|
|
94
|
+
},
|
|
95
|
+
readonly [2]: {
|
|
96
|
+
readonly type: TypeDefType.Literal,
|
|
97
|
+
readonly valuePrototype: ['c'],
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
type C = StrictUnionTypeDef<null, U>
|
|
101
|
+
expectTypeOf<C>().toEqualTypeOf<{
|
|
102
|
+
readonly type: TypeDefType.Union,
|
|
103
|
+
readonly discriminator: null,
|
|
104
|
+
readonly unions: U,
|
|
105
|
+
}>()
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('allows unions of multiple literal options and one complex type', function () {
|
|
109
|
+
type U = {
|
|
110
|
+
readonly [1]: {
|
|
111
|
+
readonly type: TypeDefType.Literal,
|
|
112
|
+
readonly valuePrototype: ['a'],
|
|
113
|
+
},
|
|
114
|
+
readonly [2]: {
|
|
115
|
+
readonly type: TypeDefType.Literal,
|
|
116
|
+
readonly valuePrototype: ['c'],
|
|
117
|
+
},
|
|
118
|
+
readonly [0]: {
|
|
119
|
+
type: TypeDefType.List,
|
|
120
|
+
elements: {
|
|
121
|
+
type: TypeDefType.Literal,
|
|
122
|
+
valuePrototype: ['a'],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
type C = StrictUnionTypeDef<null, U>
|
|
127
|
+
expectTypeOf<C>().toEqualTypeOf<{
|
|
128
|
+
readonly type: TypeDefType.Union,
|
|
129
|
+
readonly discriminator: null,
|
|
130
|
+
readonly unions: U,
|
|
131
|
+
}>()
|
|
132
|
+
})
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
describe('assignment', function () {
|
|
136
|
+
describe('can be assigned to a non-strict equivalent type', function () {
|
|
137
|
+
type U = {
|
|
138
|
+
readonly [1]: {
|
|
139
|
+
readonly type: TypeDefType.Literal,
|
|
140
|
+
readonly valuePrototype: ['a'],
|
|
141
|
+
},
|
|
142
|
+
readonly [2]: {
|
|
143
|
+
readonly type: TypeDefType.Literal,
|
|
144
|
+
readonly valuePrototype: ['c'],
|
|
145
|
+
},
|
|
146
|
+
readonly [0]: {
|
|
147
|
+
type: TypeDefType.List,
|
|
148
|
+
elements: {
|
|
149
|
+
type: TypeDefType.Literal,
|
|
150
|
+
valuePrototype: ['a'],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
type C = StrictUnionTypeDef<null, U>
|
|
155
|
+
|
|
156
|
+
let t: UnionTypeDef<null, U>
|
|
157
|
+
it('equals type', function () {
|
|
158
|
+
expectTypeOf(t).toEqualTypeOf<C>()
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
describe('cannot be assigned to an invalid non-strict equivalent type', function () {
|
|
164
|
+
type U = {
|
|
165
|
+
readonly [2]: {
|
|
166
|
+
readonly type: TypeDefType.Literal,
|
|
167
|
+
readonly valuePrototype: ['a'],
|
|
168
|
+
},
|
|
169
|
+
readonly [1]: {
|
|
170
|
+
type: TypeDefType.List,
|
|
171
|
+
elements: {
|
|
172
|
+
type: TypeDefType.Literal,
|
|
173
|
+
valuePrototype: ['a'],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
type C = StrictUnionTypeDef<null, U>
|
|
178
|
+
|
|
179
|
+
let t: UnionTypeDef<null, U>
|
|
180
|
+
it('equals type', function () {
|
|
181
|
+
expectTypeOf<C>().not.toMatchTypeOf(t)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
})
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type SimplifyDeep,
|
|
3
|
+
type ValueOf,
|
|
4
|
+
} from 'type-fest'
|
|
5
|
+
import {
|
|
6
|
+
booleanType,
|
|
7
|
+
list,
|
|
8
|
+
nullable,
|
|
9
|
+
numberType,
|
|
10
|
+
object,
|
|
11
|
+
record,
|
|
12
|
+
stringType,
|
|
13
|
+
union,
|
|
14
|
+
} from 'types/builders'
|
|
15
|
+
import { type FlattenedTypeDefsOf } from 'types/flattened_type_defs_of'
|
|
16
|
+
import { type ValueToTypePathsOf } from 'types/value_to_type_paths_of'
|
|
17
|
+
|
|
18
|
+
describe('FlattenedJsonPathsOf', function () {
|
|
19
|
+
describe('literal', function () {
|
|
20
|
+
type T = ValueToTypePathsOf<typeof numberType>
|
|
21
|
+
|
|
22
|
+
let t: {
|
|
23
|
+
readonly $: '$',
|
|
24
|
+
}
|
|
25
|
+
it('equals expected type', function () {
|
|
26
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
describe('list', function () {
|
|
31
|
+
const builder = list(list(numberType))
|
|
32
|
+
type T = SimplifyDeep<ValueToTypePathsOf<typeof builder>>
|
|
33
|
+
|
|
34
|
+
let t: {
|
|
35
|
+
readonly $: '$',
|
|
36
|
+
readonly [_: `$.${number}`]: '$.*',
|
|
37
|
+
readonly [_: `$.${number}.${number}`]: '$.*.*',
|
|
38
|
+
}
|
|
39
|
+
it('equals expected type', function () {
|
|
40
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('record', function () {
|
|
45
|
+
const l = list(numberType)
|
|
46
|
+
const builder = record<typeof l, 'a' | 'b'>(l)
|
|
47
|
+
type T = SimplifyDeep<ValueToTypePathsOf<typeof builder>>
|
|
48
|
+
|
|
49
|
+
let t: {
|
|
50
|
+
readonly $: '$',
|
|
51
|
+
readonly [`$.a`]: '$.*',
|
|
52
|
+
readonly [`$.b`]: '$.*',
|
|
53
|
+
readonly [_: `$.a.${number}`]: '$.*.*',
|
|
54
|
+
readonly [_: `$.b.${number}`]: '$.*.*',
|
|
55
|
+
}
|
|
56
|
+
it('equals expected type', function () {
|
|
57
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('allows lookup of type path', function () {
|
|
61
|
+
expectTypeOf<T['$.a.1']>().toEqualTypeOf<'$.*.*'>()
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
describe('object', function () {
|
|
66
|
+
const builder = object()
|
|
67
|
+
.set('a', list(numberType))
|
|
68
|
+
.setOptional('b', booleanType)
|
|
69
|
+
.setReadonly('c', stringType)
|
|
70
|
+
.setReadonlyOptional('d', stringType)
|
|
71
|
+
type T = SimplifyDeep<ValueToTypePathsOf<typeof builder>>
|
|
72
|
+
|
|
73
|
+
let t: {
|
|
74
|
+
readonly $: '$',
|
|
75
|
+
readonly [`$.a`]: '$.a',
|
|
76
|
+
readonly [`$.b`]: '$.b',
|
|
77
|
+
readonly [`$.c`]: '$.c',
|
|
78
|
+
readonly [`$.d`]: '$.d',
|
|
79
|
+
readonly [_: `$.a.${number}`]: '$.a.*',
|
|
80
|
+
}
|
|
81
|
+
it('equals expected type', function () {
|
|
82
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('has the same value paths', function () {
|
|
86
|
+
type ValuePaths = keyof FlattenedTypeDefsOf<typeof builder, null>
|
|
87
|
+
expectTypeOf<ValuePaths>().toEqualTypeOf<keyof T>()
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('has the same type paths', function () {
|
|
91
|
+
type TypePaths = keyof FlattenedTypeDefsOf<typeof builder, '*'>
|
|
92
|
+
expectTypeOf<TypePaths>().toEqualTypeOf<ValueOf<T>>()
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
describe('union', function () {
|
|
97
|
+
describe('non-discriminated', function () {
|
|
98
|
+
const builder = union()
|
|
99
|
+
.add('1', list(numberType))
|
|
100
|
+
.add('2', stringType)
|
|
101
|
+
type T = SimplifyDeep<ValueToTypePathsOf<typeof builder>>
|
|
102
|
+
|
|
103
|
+
let t: {
|
|
104
|
+
readonly $: '$',
|
|
105
|
+
readonly [_: `$.${number}`]: '$.*',
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
it('equals expected type', function () {
|
|
109
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
describe('discriminated', function () {
|
|
114
|
+
const builder = union('d')
|
|
115
|
+
.add('1', object().set('a', booleanType).set('b', numberType))
|
|
116
|
+
.add('2', object().set('x', numberType).set('y', stringType))
|
|
117
|
+
type T = SimplifyDeep<ValueToTypePathsOf<typeof builder>>
|
|
118
|
+
|
|
119
|
+
let t: {
|
|
120
|
+
readonly $: '$',
|
|
121
|
+
readonly ['$.1:a']: '$.1:a',
|
|
122
|
+
readonly ['$.1:b']: '$.1:b',
|
|
123
|
+
readonly ['$.2:x']: '$.2:x',
|
|
124
|
+
readonly ['$.2:y']: '$.2:y',
|
|
125
|
+
}
|
|
126
|
+
it('equals expected type', function () {
|
|
127
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('has the same value paths', function () {
|
|
131
|
+
type ValuePaths = keyof FlattenedTypeDefsOf<typeof builder, null>
|
|
132
|
+
expectTypeOf<ValuePaths>().toEqualTypeOf<keyof T>()
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('has the same type paths', function () {
|
|
136
|
+
type TypePaths = keyof FlattenedTypeDefsOf<typeof builder, '*'>
|
|
137
|
+
expectTypeOf<TypePaths>().toEqualTypeOf<ValueOf<T>>()
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
describe('readonly', function () {
|
|
143
|
+
const builder = list(list(numberType)).readonly()
|
|
144
|
+
|
|
145
|
+
type T = SimplifyDeep<ValueToTypePathsOf<typeof builder>>
|
|
146
|
+
|
|
147
|
+
let t: {
|
|
148
|
+
readonly $: '$',
|
|
149
|
+
readonly [_: `$.${number}`]: '$.*',
|
|
150
|
+
readonly [_: `$.${number}.${number}`]: '$.*.*',
|
|
151
|
+
}
|
|
152
|
+
it('equals expected type', function () {
|
|
153
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
describe('nullable', function () {
|
|
158
|
+
const builder = nullable(list(nullable(list(numberType))))
|
|
159
|
+
|
|
160
|
+
type T = SimplifyDeep<ValueToTypePathsOf<typeof builder>>
|
|
161
|
+
|
|
162
|
+
let t: {
|
|
163
|
+
readonly $: '$',
|
|
164
|
+
readonly [_: `$.${number}`]: '$.*',
|
|
165
|
+
readonly [_: `$.${number}.${number}`]: '$.*.*',
|
|
166
|
+
}
|
|
167
|
+
it('equals expected type', function () {
|
|
168
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('has the same value paths', function () {
|
|
172
|
+
type ValuePaths = keyof FlattenedTypeDefsOf<typeof builder, null>
|
|
173
|
+
expectTypeOf<ValuePaths>().toEqualTypeOf<keyof T>()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('has the same type paths', function () {
|
|
177
|
+
type TypePaths = keyof FlattenedTypeDefsOf<typeof builder, '*'>
|
|
178
|
+
expectTypeOf<TypePaths>().toEqualTypeOf<ValueOf<T>>()
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
})
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { type SimplifyDeep } from 'type-fest'
|
|
2
|
+
import {
|
|
3
|
+
type TypeDefType,
|
|
4
|
+
} from 'types/definitions'
|
|
5
|
+
import { type ValueTypeOf } from 'types/value_type_of'
|
|
6
|
+
|
|
7
|
+
describe('ValueTypeOf', function () {
|
|
8
|
+
describe('literal', function () {
|
|
9
|
+
type TypeD = {
|
|
10
|
+
readonly type: TypeDefType.Literal,
|
|
11
|
+
readonly valuePrototype: ['a' | 'b' | 'c'],
|
|
12
|
+
}
|
|
13
|
+
type T = ValueTypeOf<{ definition: TypeD }>
|
|
14
|
+
|
|
15
|
+
let t: 'a' | 'b' | 'c'
|
|
16
|
+
it('equals expected type', function () {
|
|
17
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
describe('list', function () {
|
|
22
|
+
describe('simple', function () {
|
|
23
|
+
type TypeD = {
|
|
24
|
+
readonly type: TypeDefType.List,
|
|
25
|
+
elements: {
|
|
26
|
+
readonly type: TypeDefType.Literal,
|
|
27
|
+
readonly valuePrototype: ['a' | 'b' | 'c'],
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
type T = ValueTypeOf<{ definition: TypeD }>
|
|
31
|
+
describe('mutable', function () {
|
|
32
|
+
let a: ('a' | 'b' | 'c')[]
|
|
33
|
+
it('equals expected type', function () {
|
|
34
|
+
expectTypeOf(a).toEqualTypeOf<T>()
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe('readonly', function () {
|
|
39
|
+
type R = ValueTypeOf<{
|
|
40
|
+
definition: {
|
|
41
|
+
readonly type: TypeDefType.List,
|
|
42
|
+
readonly elements: {
|
|
43
|
+
readonly type: TypeDefType.Literal,
|
|
44
|
+
readonly valuePrototype: ['a' | 'b' | 'c'],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}>
|
|
48
|
+
|
|
49
|
+
let a: readonly ('a' | 'b' | 'c')[]
|
|
50
|
+
it('equals expected type', function () {
|
|
51
|
+
expectTypeOf(a).toEqualTypeOf<R>()
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
describe('record', function () {
|
|
58
|
+
type TypeD = {
|
|
59
|
+
readonly type: TypeDefType.Record,
|
|
60
|
+
readonly keyPrototype: 'x' | 'y' | 'z',
|
|
61
|
+
valueTypeDef: {
|
|
62
|
+
readonly type: TypeDefType.Literal,
|
|
63
|
+
readonly valuePrototype: ['a' | 'b' | 'c'],
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
type T = ValueTypeOf<{ definition: TypeD }>
|
|
67
|
+
|
|
68
|
+
describe('mutable', function () {
|
|
69
|
+
let t: Record<'x' | 'y' | 'z', 'a' | 'b' | 'c'>
|
|
70
|
+
it('equals expected type', function () {
|
|
71
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
describe('readonly', function () {
|
|
76
|
+
type R = ValueTypeOf<{
|
|
77
|
+
readonly definition: {
|
|
78
|
+
readonly type: TypeDefType.Record,
|
|
79
|
+
readonly keyPrototype: 'x' | 'y' | 'z',
|
|
80
|
+
readonly valueTypeDef: {
|
|
81
|
+
readonly type: TypeDefType.Literal,
|
|
82
|
+
readonly valuePrototype: ['a' | 'b' | 'c'],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
}>
|
|
86
|
+
let r: Readonly<Record<'x' | 'y' | 'z', 'a' | 'b' | 'c'>>
|
|
87
|
+
|
|
88
|
+
it('equals expected type', function () {
|
|
89
|
+
expectTypeOf(r).toEqualTypeOf<R>()
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
describe('partial', function () {
|
|
94
|
+
type TypeD = {
|
|
95
|
+
readonly type: TypeDefType.Record,
|
|
96
|
+
readonly keyPrototype: 'x' | 'y' | 'z',
|
|
97
|
+
valueTypeDef: {
|
|
98
|
+
readonly type: TypeDefType.Literal,
|
|
99
|
+
readonly valuePrototype: ['a' | 'b' | 'c'],
|
|
100
|
+
} | undefined,
|
|
101
|
+
}
|
|
102
|
+
type T = ValueTypeOf<{ definition: TypeD }>
|
|
103
|
+
|
|
104
|
+
let t: Partial<Record<'x' | 'y' | 'z', 'a' | 'b' | 'c'>>
|
|
105
|
+
it('equals expected type', function () {
|
|
106
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
describe('partial readonly', function () {
|
|
111
|
+
type TypeD = {
|
|
112
|
+
readonly type: TypeDefType.Record,
|
|
113
|
+
readonly keyPrototype: 'x' | 'y' | 'z',
|
|
114
|
+
readonly valueTypeDef: {
|
|
115
|
+
readonly type: TypeDefType.Literal,
|
|
116
|
+
readonly valuePrototype: ['a' | 'b' | 'c'],
|
|
117
|
+
} | undefined,
|
|
118
|
+
}
|
|
119
|
+
type T = ValueTypeOf<{ definition: TypeD }>
|
|
120
|
+
|
|
121
|
+
let t: Partial<Readonly<Record<'x' | 'y' | 'z', 'a' | 'b' | 'c'>>>
|
|
122
|
+
it('equals expected type', function () {
|
|
123
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
describe('object', function () {
|
|
129
|
+
type TypeD = {
|
|
130
|
+
readonly type: TypeDefType.Object,
|
|
131
|
+
fields: {
|
|
132
|
+
a: {
|
|
133
|
+
readonly type: TypeDefType.Literal,
|
|
134
|
+
readonly valuePrototype: ['a' | 'b'],
|
|
135
|
+
},
|
|
136
|
+
b: {
|
|
137
|
+
readonly type: TypeDefType.Literal,
|
|
138
|
+
readonly valuePrototype: [number],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
type T = ValueTypeOf<{ definition: TypeD }>
|
|
143
|
+
|
|
144
|
+
describe('mutable', function () {
|
|
145
|
+
let value: {
|
|
146
|
+
a: 'a' | 'b',
|
|
147
|
+
b: number,
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
it('equals expected type', function () {
|
|
151
|
+
expectTypeOf(value).toEqualTypeOf<T>()
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
describe('readonly', function () {
|
|
156
|
+
type TypeD = {
|
|
157
|
+
readonly type: TypeDefType.Object,
|
|
158
|
+
fields: {
|
|
159
|
+
readonly a: {
|
|
160
|
+
readonly type: TypeDefType.Literal,
|
|
161
|
+
readonly valuePrototype: ['a' | 'b'],
|
|
162
|
+
},
|
|
163
|
+
readonly b: {
|
|
164
|
+
readonly type: TypeDefType.Literal,
|
|
165
|
+
readonly valuePrototype: [number],
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
}
|
|
169
|
+
type T = ValueTypeOf<{ definition: TypeD }>
|
|
170
|
+
|
|
171
|
+
let value: {
|
|
172
|
+
readonly a: 'a' | 'b',
|
|
173
|
+
readonly b: number,
|
|
174
|
+
}
|
|
175
|
+
it('equals expected type', function () {
|
|
176
|
+
expectTypeOf(value).toEqualTypeOf<T>()
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
describe('partial', function () {
|
|
181
|
+
type TypeD = {
|
|
182
|
+
readonly type: TypeDefType.Object,
|
|
183
|
+
readonly fields: {
|
|
184
|
+
a?: {
|
|
185
|
+
readonly type: TypeDefType.Literal,
|
|
186
|
+
readonly valuePrototype: ['a' | 'b'],
|
|
187
|
+
},
|
|
188
|
+
b?: {
|
|
189
|
+
readonly type: TypeDefType.Literal,
|
|
190
|
+
readonly valuePrototype: [number],
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
}
|
|
194
|
+
type T = ValueTypeOf<{ definition: TypeD }>
|
|
195
|
+
|
|
196
|
+
let v: {
|
|
197
|
+
a?: 'a' | 'b',
|
|
198
|
+
b?: number,
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
it('equals expected type', function () {
|
|
202
|
+
expectTypeOf(v).toEqualTypeOf<T>()
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
describe('union', function () {
|
|
208
|
+
describe('non-discriminated', function () {
|
|
209
|
+
type T = ValueTypeOf<{
|
|
210
|
+
definition: {
|
|
211
|
+
readonly type: TypeDefType.Union,
|
|
212
|
+
readonly discriminator: null,
|
|
213
|
+
readonly unions: {
|
|
214
|
+
readonly [0]: {
|
|
215
|
+
readonly type: TypeDefType.Literal,
|
|
216
|
+
readonly valuePrototype: [null],
|
|
217
|
+
},
|
|
218
|
+
readonly [1]: {
|
|
219
|
+
readonly type: TypeDefType.Literal,
|
|
220
|
+
readonly valuePrototype: [number],
|
|
221
|
+
},
|
|
222
|
+
readonly [2]: {
|
|
223
|
+
readonly type: TypeDefType.Literal,
|
|
224
|
+
readonly valuePrototype: [string],
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
}>
|
|
229
|
+
|
|
230
|
+
let t: null | number | string
|
|
231
|
+
|
|
232
|
+
it('equals expected type', function () {
|
|
233
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
234
|
+
})
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
describe('implicitly discriminated', function () {
|
|
238
|
+
type T = ValueTypeOf<{
|
|
239
|
+
definition: {
|
|
240
|
+
readonly type: TypeDefType.Union,
|
|
241
|
+
readonly discriminator: null,
|
|
242
|
+
readonly unions: {
|
|
243
|
+
readonly [0]: {
|
|
244
|
+
readonly type: TypeDefType.Object,
|
|
245
|
+
readonly fields: {
|
|
246
|
+
b: {
|
|
247
|
+
readonly type: TypeDefType.Literal,
|
|
248
|
+
readonly valuePrototype: [string],
|
|
249
|
+
},
|
|
250
|
+
readonly d: {
|
|
251
|
+
readonly type: TypeDefType.Literal,
|
|
252
|
+
readonly valuePrototype: [1],
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
readonly [1]: {
|
|
257
|
+
readonly type: TypeDefType.Object,
|
|
258
|
+
readonly fields: {
|
|
259
|
+
b: {
|
|
260
|
+
readonly type: TypeDefType.Literal,
|
|
261
|
+
readonly valuePrototype: [number],
|
|
262
|
+
},
|
|
263
|
+
readonly d: {
|
|
264
|
+
readonly type: TypeDefType.Literal,
|
|
265
|
+
readonly valuePrototype: [2],
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
}>
|
|
272
|
+
|
|
273
|
+
let t: {
|
|
274
|
+
readonly d: 1,
|
|
275
|
+
b: string,
|
|
276
|
+
} | {
|
|
277
|
+
readonly d: 2,
|
|
278
|
+
b: number,
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
it('equals expected type', function () {
|
|
282
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
283
|
+
})
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
describe('explicitly discriminated', function () {
|
|
287
|
+
type T = SimplifyDeep<
|
|
288
|
+
ValueTypeOf<{
|
|
289
|
+
definition: {
|
|
290
|
+
readonly type: TypeDefType.Union,
|
|
291
|
+
readonly discriminator: 'd',
|
|
292
|
+
readonly unions: {
|
|
293
|
+
readonly [1]: {
|
|
294
|
+
readonly type: TypeDefType.Object,
|
|
295
|
+
readonly fields: {
|
|
296
|
+
b: {
|
|
297
|
+
readonly type: TypeDefType.Literal,
|
|
298
|
+
readonly valuePrototype: [string],
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
readonly [2]: {
|
|
303
|
+
readonly type: TypeDefType.Object,
|
|
304
|
+
readonly fields: {
|
|
305
|
+
b: {
|
|
306
|
+
readonly type: TypeDefType.Literal,
|
|
307
|
+
readonly valuePrototype: [number],
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
}>
|
|
314
|
+
>
|
|
315
|
+
|
|
316
|
+
let t: {
|
|
317
|
+
readonly d: 1,
|
|
318
|
+
b: string,
|
|
319
|
+
} | {
|
|
320
|
+
readonly d: 2,
|
|
321
|
+
b: number,
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
it('equals expected type', function () {
|
|
325
|
+
expectTypeOf(t).toEqualTypeOf<T>()
|
|
326
|
+
})
|
|
327
|
+
})
|
|
328
|
+
})
|
|
329
|
+
})
|