mol_type_all 0.0.1828 → 0.0.1829

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/README.md CHANGED
@@ -2,18 +2,18 @@
2
2
 
3
3
  Collection of TypeScript meta types for complex logic.
4
4
 
5
- ![Type Asserts](https://i.imgur.com/CNI5KvX.png)
5
+ # Usage
6
6
 
7
- # MAM Usage
7
+ ## MAM
8
8
 
9
9
  ```typescript
10
- type first_of_tuple = $mol_type_assert<
11
- $mol_type_head<[ 1 , 2 , 3 ]> ,
12
- 1
10
+ type cutted_head = $mol_type_assert<
11
+ $mol_type_tail<[ 1, 2, 3 ]>,
12
+ [ 2, 3 ]
13
13
  >
14
14
  ```
15
15
 
16
- # NPM usage
16
+ ## NPM
17
17
 
18
18
  ```sh
19
19
  npm install mol_type_all
@@ -21,17 +21,87 @@ npm install mol_type_all
21
21
 
22
22
  ```typescript
23
23
  import {
24
- $mol_type_assert as Assert ,
25
- $mol_type_head as Head ,
24
+ $mol_type_assert as Assert,
25
+ $mol_type_tail as Tail,
26
26
  } from 'mol_type_all'
27
27
 
28
- type first_of_tuple = Assert<
29
- Head<[ 1 , 2 , 3 ]> ,
30
- 1
28
+ type cutted_head = Assert<
29
+ Tail<[ 1, 2, 3 ]>,
30
+ [ 2, 3 ]
31
31
  >
32
32
  ```
33
33
 
34
- [![Edit $mol_type example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/moltype-example-1ebxp)
34
+ # Utilite types
35
+
36
+ ## Assertions
37
+
38
+ - [$mol_type_error](./error) - special type for errors with details.
39
+ - [$mol_type_assert](./assert) - fails type check on type inequality.
40
+ - [$mol_type_enforce](./enforce) - fails type check on type incompatibility.
41
+
42
+ ```ts
43
+ // Actual result
44
+ type partial_record = $mol_type_assert<
45
+ Partial<{ foo: 123 }>, // Some expression
46
+ { foo?: 123 } // Expected result
47
+ >
48
+ ```
49
+
50
+ ![Type Asserts](https://habrastorage.org/webt/a4/d3/d6/a4d3d643f36e4ac3f431b9dac7a1f2c5.png)
51
+
52
+ ## Tuples
53
+
54
+ - [$mol_type_head](./head) - first item of tuple or never.
55
+ - [$mol_type_head_write](./head/write) - replaces first element of tuple.
56
+ - [$mol_type_tail](./tail) - tuple without first item.
57
+ - [$mol_type_foot](./foot) - last item of tuple or never.
58
+ - [$mol_type_reverse](./reverse) - makes reversed tuple.
59
+
60
+ ## Algebraics
61
+
62
+ - [$mol_type_equals](./equals) - check for types equality.
63
+ - [$mol_type_access](./access) - takes type of property from wild union type.
64
+ - [$mol_type_filter_keys](./filter/keys) - records from union with provided property.
65
+ - [$mol_type_intersect](./intersect) - converts union to intersection.
66
+ - [$mol_type_merge](./merge) - merges intersection of records to one record.
67
+ - [$mol_type_keys_all](./keys/all) - all keys from all records from union.
68
+
69
+ ## Strings
70
+
71
+ - [$mol_type_alphabet_*](./alphabet) - character classes.
72
+ - [$mol_type_string_split](./string/split) - splits string by separator.
73
+ - [$mol_type_string_join](./string/join) - joins strings by separator.
74
+
75
+ ## Numbers
76
+
77
+ - [$mol_type_int_*](./int) - integer arithmetic (`+`, `-`, `*`, `/`, `^`, `..`, `()`, `<`)
78
+
79
+ ## Functions
80
+
81
+ - [$mol_type_unary](./unary) - function/class with single param.
82
+ - [$mol_type_param](./param) - takes param type by index.
83
+ - [$mol_type_result](./result) - takes result/instance type.
84
+
85
+ ## Records
86
+
87
+ - [$mol_type_immutable_deep](./immutable/deep) - recursive immutability.
88
+ - [$mol_type_mutable_deep](./mutable/deep) - recursive mutability.
89
+ - [$mol_type_partial_undefined](./partial/undefined) - makes all properties partial.
90
+ - [$mol_type_partial_deep](./partial/deep) - makes all properties partial deeply.
91
+ - [$mol_type_required_deep](./required/deep) - makes all properties required deeply.
92
+ - [$mol_type_nullable](./nullable) - makes all properties nullable.
93
+ - [$mol_type_writable](./writable) - makes all properties writable.
94
+ - [$mol_type_keys_extract](./keys/extract) - extracts key names from record by value type.
95
+ - [$mol_type_keys_exclude](./keys/exclude) - excludes key names from record by value type.
96
+ - [$mol_type_omit](./omit) - omits properties by value type.
97
+ - [$mol_type_pick](./pick) - pick properties by value type.
98
+ - [$mol_type_override](./override) - fully replaces properties.
99
+ - [$mol_type_case_*](./case) - converts keys/values to upper/lower/capital cases.
100
+
101
+ - [$mol_type_flat_camel](./flat/camel) - makes flat record from volume records tree.
102
+ - [$mol_type_flat_keys](./flat/keys) - takes keys paths from volume records tree.
103
+ - [$mol_type_volume](./volume) - makes volume records tree from flat record.
104
+ - [$mol_type_volume_value](./volume/value) - takes value from volume records tree by path.
35
105
 
36
106
  # Similar Projects
37
107
 
package/node.d.ts CHANGED
@@ -14,6 +14,46 @@ declare namespace $ {
14
14
  export {};
15
15
  }
16
16
 
17
+ declare namespace $ {
18
+ /**
19
+ * Leave types with specified keys in union type
20
+ *
21
+ * // { prop: number; foo: number }
22
+ * type only_with_prop = $mol_type_filter_keys< { prop: number; foo: number } | { foo: string }, 'prop' >
23
+ */
24
+ type $mol_type_filter_keys<Type, Keys extends string | number> = Extract<Type, {
25
+ [_ in Keys]?: any;
26
+ }>;
27
+ }
28
+
29
+ declare namespace $ {
30
+ /**
31
+ * Access property type by key for union type
32
+ *
33
+ * // number
34
+ * type a_type = $mol_type_access< { a: number } | boolean, 'a' >
35
+ */
36
+ type $mol_type_access<Type, Keys extends string | number> = $mol_type_filter_keys<Type, Keys> extends never ? never : Keys extends keyof $mol_type_filter_keys<Type, Keys> ? $mol_type_filter_keys<Type, Keys>[Keys] : never;
37
+ }
38
+
39
+ declare namespace $ {
40
+ /** English alphabet in lowercase **/
41
+ type $mol_type_alphabet_en_lower = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'j' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
42
+ /** English alphabet in uppercase **/
43
+ type $mol_type_alphabet_en_upper = Uppercase<$mol_type_alphabet_en_lower>;
44
+ /** English alphabet **/
45
+ type $mol_type_alphabet_en = $mol_type_alphabet_en_lower | $mol_type_alphabet_en_upper;
46
+ }
47
+
48
+ declare namespace $ {
49
+ /** Russian alphabet in lowercase **/
50
+ type $mol_type_alphabet_ru_lower = 'а' | 'б' | 'в' | 'г' | 'д' | 'е' | 'ё' | 'ж' | 'з' | 'и' | 'й' | 'к' | 'л' | 'м' | 'н' | 'о' | 'п' | 'р' | 'с' | 'т' | 'у' | 'ф' | 'х' | 'ц' | 'ч' | 'ш' | 'щ' | 'ъ' | 'ы' | 'ь' | 'э' | 'ю' | 'я';
51
+ /** Russian alphabet in uppercase **/
52
+ type $mol_type_alphabet_ru_upper = Uppercase<$mol_type_alphabet_ru_lower>;
53
+ /** Russian alphabet **/
54
+ type $mol_type_alphabet_ru = $mol_type_alphabet_ru_lower | $mol_type_alphabet_ru_upper;
55
+ }
56
+
17
57
  declare namespace $ {
18
58
  /**
19
59
  * Return `unknown` when `A` and `B` are the same type. `never` otherwise.
@@ -25,6 +65,7 @@ declare namespace $ {
25
65
  }
26
66
 
27
67
  declare namespace $ {
68
+ /** Returns error type, that don't match to normal value. */
28
69
  type $mol_type_error<Message, Info = {}> = Message & {
29
70
  $mol_type_error: Info;
30
71
  };
@@ -47,6 +88,142 @@ declare namespace $ {
47
88
  type $mol_type_assert_never<Actual extends never> = Actual;
48
89
  }
49
90
 
91
+ declare namespace $ {
92
+ /**
93
+ * Capitalize type keys.
94
+ *
95
+ * // { Foo: 1; Bar: 2 }
96
+ * $mol_type_case_capital_keys< { foo: 1; bar: 2 } >
97
+ */
98
+ type $mol_type_case_capital_keys<Type> = {
99
+ [Key in keyof Type as Capitalize<Extract<Key, string>>]: Type[Key];
100
+ };
101
+ /**
102
+ * Capitalize type values.
103
+ *
104
+ * // { foo: 'Bar' }
105
+ * $mol_type_case_capital_values< { foo: 'bar' } >
106
+ */
107
+ type $mol_type_case_capital_values<Type> = {
108
+ [Key in keyof Type]: Capitalize<Extract<Type[Key], string>>;
109
+ };
110
+ }
111
+
112
+ declare namespace $ {
113
+ /**
114
+ * Lowercase type keys.
115
+ *
116
+ * // { foo: 'BAR' }
117
+ * $mol_type_case_lower_keys< { FOO: 'BAR' } >
118
+ */
119
+ type $mol_type_case_lower_keys<Type> = {
120
+ [Key in keyof Type as Lowercase<Extract<Key, string>>]: Type[Key];
121
+ };
122
+ /**
123
+ * Lowercase type values.
124
+ *
125
+ * // { FOO: 'bar' }
126
+ * $mol_type_case_lower_values< { FOO: 'BAR' } >
127
+ */
128
+ type $mol_type_case_lower_values<Type> = {
129
+ [Key in keyof Type]: Lowercase<Extract<Type[Key], string>>;
130
+ };
131
+ }
132
+
133
+ declare namespace $ {
134
+ /**
135
+ * Uppercase type keys.
136
+ *
137
+ * // { FOO: 'bar' }
138
+ * $mol_type_case_upper_keys< { foo: 'bar' } >
139
+ */
140
+ type $mol_type_case_upper_keys<Type> = {
141
+ [Key in keyof Type as Uppercase<Extract<Key, string>>]: Type[Key];
142
+ };
143
+ /**
144
+ * Uppercase type values.
145
+ *
146
+ * // { foo: 'BAR' }
147
+ * $mol_type_case_upper_values< { foo: 'bar' } >
148
+ */
149
+ type $mol_type_case_upper_values<Type> = {
150
+ [Key in keyof Type]: Uppercase<Extract<Type[Key], string>>;
151
+ };
152
+ }
153
+
154
+ declare namespace $ {
155
+ /**
156
+ * Fails if `Actual` type is not subtype of `Expected`.
157
+ */
158
+ type $mol_type_enforce<Actual extends Expected, Expected> = Actual;
159
+ }
160
+
161
+ declare namespace $ {
162
+ /**
163
+ * Reqursive converts intersection of records to record of intersections
164
+ *
165
+ * // { a : { x : 1 , y : 2 } }
166
+ * $mol_type_merge< { a : { x : 1 } }&{ a : { y : 2 } } >
167
+ */
168
+ type $mol_type_merge<Intersection> = Intersection extends (...a: any[]) => any ? Intersection : Intersection extends new (...a: any[]) => any ? Intersection : Intersection extends object ? $mol_type_merge_object<Intersection> extends Intersection ? unknown extends $mol_type_equals<{
169
+ [Key in keyof Intersection]: Intersection[Key];
170
+ }, Intersection> ? Intersection : {
171
+ [Key in keyof Intersection]: $mol_type_merge<Intersection[Key]>;
172
+ } : Intersection : Intersection;
173
+ /**
174
+ * Flat converts intersection of records to record of intersections
175
+ *
176
+ * // { a: 1, b: 2 }
177
+ * $mol_type_merge< { a: 1 } & { b: 2 } >
178
+ */
179
+ type $mol_type_merge_object<Intersection> = {
180
+ [Key in keyof Intersection]: Intersection[Key];
181
+ };
182
+ }
183
+
184
+ declare namespace $ {
185
+ /** Replaces properties of `Base` record by properties from `Over`. */
186
+ type $mol_type_override<Base, Over> = $mol_type_merge<Omit<Base, keyof Over> & Over>;
187
+ }
188
+
189
+ declare namespace $ {
190
+ /**
191
+ * Fields that can be set to undefined makes optional
192
+ *
193
+ * type User = $mol_type_partial_undefined<{ name : string , age : number | undefined }> // { name : string , age? : number | undefined }
194
+ */
195
+ type $mol_type_partial_undefined<Val> = $mol_type_merge<$mol_type_override<Partial<Val>, Pick<Val, {
196
+ [Field in keyof Val]: undefined extends Val[Field] ? never : Field;
197
+ }[keyof Val]>>>;
198
+ }
199
+
200
+ declare namespace $ {
201
+ /**
202
+ * Flat structure key names, leading to non-object types, in tuples. Endpoint specifies structures, whose keys should not be flat.
203
+ *
204
+ * // [ 'a', 'd' ] | [ 'a', 'b', 'c' ]
205
+ * type keys = $mol_type_flat_keys< { a: { b: { c: number }, d: string } } >
206
+ */
207
+ type $mol_type_flat_keys<Type, Endpoint = never> = Type extends object ? Type extends Readonly<Array<any>> | Function | Promise<any> ? [] : Type extends Endpoint ? [] : {
208
+ [Key in keyof Type]-?: Key extends string ? [
209
+ Key,
210
+ ...$mol_type_flat_keys<Required<Type>[Key], Endpoint>
211
+ ] : never;
212
+ }[keyof Type] : [];
213
+ /**
214
+ * All flat structure key names in tuples. Endpoint specifies structures, whose keys should not be flat.
215
+ *
216
+ * // [ 'a' ] | [ 'a', 'b' ] | [ 'a', 'd' ] | [ 'a', 'b', 'c' ]
217
+ * type all_keys = $mol_type_flat_keys_all< { a: { b: { c: number }, d: string } } >
218
+ */
219
+ type $mol_type_flat_keys_all<Type, Endpoint = never> = Type extends object ? Type extends Readonly<Array<any>> | Promise<any> ? [] : Type extends Endpoint ? [] : {
220
+ [Key in keyof Type]-?: Key extends string ? [Key] | [
221
+ Key,
222
+ ...$mol_type_flat_keys_all<Required<Type>[Key], Endpoint>
223
+ ] : never;
224
+ }[keyof Type] : [];
225
+ }
226
+
50
227
  declare namespace $ {
51
228
  /**
52
229
  * Returns `Tuple` without first element.
@@ -58,11 +235,28 @@ declare namespace $ {
58
235
 
59
236
  declare namespace $ {
60
237
  /**
61
- * Returns `Tuple` pushed by `Item`.
238
+ * Join strings with `Separator`.
239
+ *
240
+ * // 'foo%bar%wee'
241
+ * $mol_type_string_join< [ 'foo', 'bar', 'wee' ], '%' >
242
+ */
243
+ type $mol_type_string_join<Parts extends Array<string>, Separator extends string> = Parts['length'] extends 0 ? never : Parts['length'] extends 1 ? Parts[0] : Parts['length'] extends 2 ? `${Extract<Parts[0], string>}${'' extends Parts[1] ? '' : Separator}${Extract<Parts[1], string>}` : $mol_type_string_join<[
244
+ $mol_type_string_join<[Parts[0], Parts[1]], Separator>,
245
+ ...$mol_type_tail<$mol_type_tail<Parts>>
246
+ ], Separator>;
247
+ }
248
+
249
+ declare namespace $ {
250
+ /**
251
+ * Split string into parts with separator.
62
252
  *
63
- * $mol_type_tail< [ 1 , 2 ] , 3 > // [ 1 , 2 , 3 ]
253
+ * // [ 'foo', 'bar', 'wee' ]
254
+ * $mol_type_string_split< 'foo-bar-wee', '-' >
64
255
  */
65
- type $mol_type_append<Tuple extends readonly any[], Item extends any> = [...Tuple, Item];
256
+ type $mol_type_string_split<String extends string, Separator extends string = ''> = '' extends String ? [] : String extends `${infer Left}${Separator}${infer Right}` ? [
257
+ ...('' extends Left ? [] : [Left]),
258
+ ...$mol_type_string_split<Right, Separator>
259
+ ] : [String];
66
260
  }
67
261
 
68
262
  declare namespace $ {
@@ -74,6 +268,198 @@ declare namespace $ {
74
268
  type $mol_type_head<Tuple extends readonly any[]> = Tuple['length'] extends 0 ? never : Tuple[0];
75
269
  }
76
270
 
271
+ declare namespace $ {
272
+ /**
273
+ * Join strings in snake_case.
274
+ *
275
+ * // 'foo_bar_wee'
276
+ * $mol_type_case_snake< [ 'foo', 'bar', 'wee' ] >
277
+ */
278
+ export type $mol_type_case_snake<Parts extends Array<string>> = $mol_type_string_join<Parts, '_'>;
279
+ /**
280
+ * Parse snake_case string into parts.
281
+ *
282
+ * // [ 'foo', 'bar', 'wee' ]
283
+ * $mol_type_case_snake_parse< 'foo_bar_wee' >
284
+ */
285
+ export type $mol_type_case_snake_parse<String extends string> = $mol_type_string_split<String, '_'>;
286
+ /**
287
+ * Join strings in kebab-case.
288
+ *
289
+ * // 'foo-bar-wee'
290
+ * $mol_type_case_kebab< [ 'foo', 'bar', 'wee' ] >
291
+ */
292
+ export type $mol_type_case_kebab<Parts extends Array<string>> = $mol_type_string_join<Parts, '-'>;
293
+ /**
294
+ * Parse kebab-case string into parts.
295
+ *
296
+ * // [ 'foo', 'bar', 'wee' ]
297
+ * $mol_type_case_kebab_parse< 'foo-bar-wee' >
298
+ */
299
+ export type $mol_type_case_kebab_parse<String extends string> = $mol_type_string_split<String, '-'>;
300
+ /**
301
+ * Join strings in dot.case.
302
+ *
303
+ * // 'foo.bar.wee'
304
+ * $mol_type_case_dot< [ 'foo', 'bar', 'wee' ] >
305
+ */
306
+ export type $mol_type_case_dot<Parts extends Array<string>> = $mol_type_string_join<Parts, '.'>;
307
+ /**
308
+ * Parse dot.case string into parts.
309
+ *
310
+ * // [ 'foo', 'bar', 'wee' ]
311
+ * $mol_type_case_dot_parse< 'foo.bar.wee' >
312
+ */
313
+ export type $mol_type_case_dot_parse<String extends string> = $mol_type_string_split<String, '.'>;
314
+ /**
315
+ * Join strings in camelCase.
316
+ *
317
+ * // 'fooBarWee'
318
+ * $mol_type_case_camel< [ 'foo', 'bar', 'wee' ] >
319
+ */
320
+ export type $mol_type_case_camel<Parts extends Array<string>> = $mol_type_string_join<[
321
+ Lowercase<$mol_type_head<Parts>>,
322
+ ...Extract<$mol_type_case_capital_values<$mol_type_case_lower_values<$mol_type_tail<Parts>>>, Array<string>>
323
+ ], ''>;
324
+ type camel_temp_separator = '.';
325
+ type camel_replace_with_separator<String extends string> = String extends `${infer Left}${infer Right}` ? `${Left extends Capitalize<Left> ? camel_temp_separator : ''}${Lowercase<Left>}${camel_replace_with_separator<Right>}` : String;
326
+ /**
327
+ * Parse camelCase string into parts.
328
+ *
329
+ * // [ 'foo', 'bar', 'wee' ]
330
+ * $mol_type_case_camel_parse< 'fooBarWee' >
331
+ */
332
+ export type $mol_type_case_camel_parse<String extends string> = $mol_type_string_split<camel_replace_with_separator<String>, camel_temp_separator>;
333
+ /**
334
+ * Join strings in PascalCase.
335
+ *
336
+ * // 'FooBarWee'
337
+ * $mol_type_case_pascal< [ 'foo', 'bar', 'wee' ] >
338
+ */
339
+ export type $mol_type_case_pascal<Parts extends Array<string>> = $mol_type_string_join<$mol_type_case_capital_values<$mol_type_case_lower_values<Parts>>, ''>;
340
+ /**
341
+ * Parse PascalCase string into parts.
342
+ *
343
+ * // [ 'foo', 'bar', 'wee' ]
344
+ * $mol_type_case_pascal_parse< 'FooBarWee' >
345
+ */
346
+ export type $mol_type_case_pascal_parse<String extends string> = $mol_type_case_camel_parse<String>;
347
+ /**
348
+ * Join strings in Cobra_case.
349
+ *
350
+ * // 'Foo_bar_wee'
351
+ * $mol_type_case_cobra< [ 'foo', 'bar', 'wee' ] >
352
+ */
353
+ export type $mol_type_case_cobra<Parts extends Array<string>> = $mol_type_string_join<[
354
+ Capitalize<Lowercase<$mol_type_head<Parts>>>,
355
+ ...Extract<$mol_type_case_lower_values<$mol_type_tail<Parts>>, Array<string>>
356
+ ], '_'>;
357
+ /**
358
+ * Parse Cobra_case string into parts.
359
+ *
360
+ * // [ 'foo', 'bar', 'wee' ]
361
+ * $mol_type_case_cobra_parse< 'Foo_bar_wee' >
362
+ */
363
+ export type $mol_type_case_cobra_parse<String extends string> = $mol_type_case_lower_values<$mol_type_string_split<String, '_'>>;
364
+ /**
365
+ * Join strings in SCREAM_CASE.
366
+ *
367
+ * // 'FOO_BAR_WEE'
368
+ * $mol_type_case_scream< [ 'foo', 'bar', 'wee' ] >
369
+ */
370
+ export type $mol_type_case_scream<Parts extends Array<string>> = $mol_type_string_join<$mol_type_case_upper_values<Parts>, '_'>;
371
+ /**
372
+ * Parse SCREAM_CASE string into parts.
373
+ *
374
+ * // [ 'foo', 'bar', 'wee' ]
375
+ * $mol_type_case_scream_parse< 'FOO_BAR_WEE' >
376
+ */
377
+ export type $mol_type_case_scream_parse<String extends string> = $mol_type_case_cobra_parse<String>;
378
+ export {};
379
+ }
380
+
381
+ declare namespace $ {
382
+ /**
383
+ * Converts union of types to intersection of same types
384
+ *
385
+ * $mol_type_intersect< number | string > // number & string
386
+ */
387
+ type $mol_type_intersect<Union> = (Union extends any ? (_: Union) => void : never) extends ((_: infer Intersection) => void) ? Intersection : never;
388
+ }
389
+
390
+ declare namespace $ {
391
+ /**
392
+ * Volume structure from flat with dot.case key names.
393
+ *
394
+ * // { a: { b: number; c: { d: string } } }
395
+ * type volume = $mol_type_volume< { 'a.b': number; 'a.c.d': string } >
396
+ */
397
+ type $mol_type_volume<Type extends object> = $mol_type_merge<$mol_type_intersect<{
398
+ [Key in keyof Type]: Key extends `${infer Left}.${infer Right}` ? {
399
+ [_ in Left]: $mol_type_volume<{
400
+ [_ in Right]: Type[Key];
401
+ }>;
402
+ } : $mol_type_partial_undefined<{
403
+ [_ in Key]: Type[Key];
404
+ }>;
405
+ }[keyof Type]>>;
406
+ }
407
+
408
+ declare namespace $ {
409
+ /**
410
+ * Get value type by flat key name.
411
+ *
412
+ * // number
413
+ * type abc_type = $mol_type_volume_value< { a: { b: { c: number }; d: string }, 'a.b.c' } >
414
+ */
415
+ type $mol_type_volume_value<Type, Key extends string> = $mol_type_access<Type, Key> extends never ? Key extends `${infer Left}.${infer Right}` ? $mol_type_access<Type, Left> extends never ? never : $mol_type_volume_value<$mol_type_access<Type, Left>, Right> : never : $mol_type_access<Type, Key>;
416
+ }
417
+
418
+ declare namespace $ {
419
+ /**
420
+ * Make flat structure from volume. Camel case is used for key names.
421
+ *
422
+ * // { fooBarWee: number; fooToo: string }
423
+ * type flat = $mol_type_flat_camel< { foo: { bar: { wee: number }; too: string } } >
424
+ */
425
+ type $mol_type_flat_camel<Type, Endpoint = never> = $mol_type_partial_undefined<{
426
+ [FlatKeys in $mol_type_flat_keys<Type, Endpoint> as $mol_type_case_camel<FlatKeys>]: $mol_type_volume_value<Type, $mol_type_case_dot<FlatKeys>>;
427
+ }>;
428
+ }
429
+
430
+ declare namespace $ {
431
+ /**
432
+ * Returns last element of `Tuple`.
433
+ *
434
+ * $mol_type_tail<[ 1 , 2 , 3 ]> // 3
435
+ */
436
+ type $mol_type_foot<Tuple extends readonly any[]> = Tuple['length'] extends 0 ? never : Tuple[$mol_type_tail<Tuple>['length']];
437
+ }
438
+
439
+ declare namespace $ {
440
+ /**
441
+ * Overwrite `Tuple` first element.
442
+ *
443
+ * // [ 'd', 'b', 'c' ]
444
+ * $mol_type_head_write< [ 'a', 'b', 'c' ], 'd' >
445
+ */
446
+ type $mol_type_head_write<Tuple extends Array<any>, Over> = [
447
+ Over,
448
+ ...$mol_type_tail<Tuple>
449
+ ];
450
+ }
451
+
452
+ declare namespace $ {
453
+ /**
454
+ * Recursive `Readonly`.
455
+ *
456
+ * let props : $mol_type_immutable_deep< { foo: number[] } > = { readonly foo: readonly number[] }
457
+ */
458
+ type $mol_type_immutable_deep<Val> = {
459
+ readonly [field in keyof Val]: $mol_type_immutable_deep<Val[field]>;
460
+ };
461
+ }
462
+
77
463
  declare namespace $ {
78
464
  type Parse<Str extends string, Res extends Int = Zero> = Str extends `${infer Letter extends keyof Digits}${infer Tail}` ? Parse<Tail, Plus<[
79
465
  Mult<[Res, Ten]>,
@@ -154,11 +540,11 @@ declare namespace $ {
154
540
 
155
541
  declare namespace $ {
156
542
  /**
157
- * Converts union of types to intersection of same types
543
+ * All keys from union type
158
544
  *
159
- * $mol_type_intersect< number | string > // number & string
545
+ * type keys_all = $mol_type_keys_all< { a: number } | { b: string } > // 'a' | 'b'
160
546
  */
161
- type $mol_type_intersect<Union> = (Union extends any ? (_: Union) => void : never) extends ((_: infer Intersection) => void) ? Intersection : never;
547
+ type $mol_type_keys_all<Type> = Type extends Type ? keyof Type : never;
162
548
  }
163
549
 
164
550
  declare namespace $ {
@@ -185,25 +571,25 @@ declare namespace $ {
185
571
 
186
572
  declare namespace $ {
187
573
  /**
188
- * Reqursive converts intersection of records to record of intersections
574
+ * Recursive `-Readonly`.
189
575
  *
190
- * // { a : { x : 1 , y : 2 } }
191
- * $mol_type_merge< { a : { x : 1 } }&{ a : { y : 2 } } >
576
+ * let props : $mol_type_mutable< { readonly foo: number[] } > = { foo: number[] }
192
577
  */
193
- type $mol_type_merge<Intersection> = Intersection extends (...a: any[]) => any ? Intersection : Intersection extends new (...a: any[]) => any ? Intersection : Intersection extends object ? $mol_type_merge_object<Intersection> extends Intersection ? unknown extends $mol_type_equals<{
194
- [Key in keyof Intersection]: Intersection[Key];
195
- }, Intersection> ? Intersection : {
196
- [Key in keyof Intersection]: $mol_type_merge<Intersection[Key]>;
197
- } : Intersection : Intersection;
578
+ type $mol_type_mutable_deep<Val> = {
579
+ -readonly [field in keyof Val]: $mol_type_mutable_deep<Val[field]>;
580
+ };
581
+ }
582
+
583
+ declare namespace $ {
198
584
  /**
199
- * Flat converts intersection of records to record of intersections
585
+ * Null union with properties or with type itself.
200
586
  *
201
- * // { a: 1, b: 2 }
202
- * $mol_type_merge< { a: 1 } & { b: 2 } >
587
+ * // { foo: number | null; bar: string | null }
588
+ * $mol_type_nullable< { foo: number; bar: string } >
203
589
  */
204
- type $mol_type_merge_object<Intersection> = {
205
- [Key in keyof Intersection]: Intersection[Key];
206
- };
590
+ type $mol_type_nullable<Type> = Type extends object ? {
591
+ [Key in keyof Type]: Type[Key] | null;
592
+ } : Type | null;
207
593
  }
208
594
 
209
595
  declare namespace $ {
@@ -236,21 +622,6 @@ declare namespace $ {
236
622
  } : Val;
237
623
  }
238
624
 
239
- declare namespace $ {
240
- type $mol_type_override<Base, Over> = Omit<Base, keyof Over> & Over;
241
- }
242
-
243
- declare namespace $ {
244
- /**
245
- * Fields that can be set to undefined makes optional
246
- *
247
- * type User = $mol_type_partial_undefined<{ name : string , age : number | undefined }> // { name : string , age? : number | undefined }
248
- */
249
- type $mol_type_partial_undefined<Val> = $mol_type_merge<$mol_type_override<Partial<Val>, Pick<Val, {
250
- [Field in keyof Val]: undefined extends Val[Field] ? never : Field;
251
- }[keyof Val]>>>;
252
- }
253
-
254
625
  declare namespace $ {
255
626
  /**
256
627
  * Picks keys from `Input` which values extends `Upper`.
@@ -262,11 +633,13 @@ declare namespace $ {
262
633
 
263
634
  declare namespace $ {
264
635
  /**
265
- * Returns `Tuple` unshifted by `Item`.
636
+ * Recursive `Required`.
266
637
  *
267
- * $mol_type_tail< 1 , [ 2 , 3 ] > // [ 1 , 2 , 3 ]
638
+ * type req = $mol_type_required_deep< { a?: { b?: number } } > // { a: { b: number } }
268
639
  */
269
- type $mol_type_prepend<Item extends any, Tuple extends readonly any[]> = ((head: Item, ...args: Tuple) => any) extends ((...args: infer Result) => any) ? Result : never;
640
+ type $mol_type_required_deep<Type> = Type extends object ? Type extends Function ? Exclude<Type, undefined> : {
641
+ [Key in keyof Type]-?: $mol_type_required_deep<Type[Key]>;
642
+ } : Exclude<Type, undefined>;
270
643
  }
271
644
 
272
645
  declare namespace $ {
@@ -284,13 +657,16 @@ declare namespace $ {
284
657
 
285
658
  declare namespace $ {
286
659
  /**
287
- * Returns reversed `Tuple`.
660
+ * Returns reversed tuple.
288
661
  *
289
- * $mol_type_reverse< [ 1 , 2 ,3 ] > // [ 3 , 2 , 1 ]
662
+ * $mol_type_reverse< [ 1, 2, 3 ] > // [ 3, 2, 1 ]
290
663
  */
291
664
  type $mol_type_reverse<Tuple extends readonly any[], Reversed extends readonly any[] = []> = {
292
665
  0: Reversed;
293
- 1: $mol_type_reverse<$mol_type_tail<Tuple>, $mol_type_prepend<$mol_type_head<Tuple>, Reversed>>;
666
+ 1: $mol_type_reverse<$mol_type_tail<Tuple>, [
667
+ $mol_type_head<Tuple>,
668
+ ...Reversed
669
+ ]>;
294
670
  }[Tuple['length'] extends 0 ? 0 : 1];
295
671
  }
296
672
 
@@ -301,5 +677,11 @@ declare namespace $ {
301
677
  type $mol_type_unary = $mol_type_unary_func | $mol_type_unary_class;
302
678
  }
303
679
 
680
+ declare namespace $ {
681
+ type $mol_type_writable<T> = {
682
+ -readonly [P in keyof T]: T[P];
683
+ };
684
+ }
685
+
304
686
  export = $;
305
687
  //# sourceMappingURL=node.d.ts.map