@kakasoo/deep-strict-types 2.0.2 → 2.0.4

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
@@ -1,20 +1,48 @@
1
- # How To Use
1
+ # DeepStrictTypes Library Documentation
2
+
3
+ - [한국어 설명](./docs/README_KO.md)
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Introduction](#introduction)
8
+ 2. [DeepStrictObjectKeys](#deepstrictobjectkeys)
9
+ 3. [DeepStrictOmit](#deepstrictomit)
10
+ 4. [DeepStrictPick](#deepstrictpick)
11
+ 5. [StringToDeepObject](#stringtodeepobject)
12
+ 6. [DeepStrictMerge](#deepstrictmerge)
13
+ 7. [DeepDateToString](#deepdatetostring)
14
+
15
+ ## Introduction
16
+
17
+ DeepStrictTypes is a tool that takes TypeScript’s type manipulation to the next level.
18
+ It helps you safely perform tasks like `Omit` and `Pick` even with complex nested objects or arrays.
19
+ By addressing the limitations of TypeScript’s built-in utility types, it allows you to easily handle internal keys with strict and precise type inference.
20
+
21
+ Key features include:
22
+
23
+ - **Safe Nested Key Extraction:** It extracts all keys from within an object, boosting type safety.
24
+ - **Precise Type Manipulation:** You can pick or omit only the keys you need even in deeply nested structures, making it easier to work with complex data.
25
+ - **Unbranding and Merging:** It removes unnecessary constraints from branded types and safely merges multiple types.
26
+ - **Utility Function Support (Experimental):** It even provides runtime functions to further ensure type safety during development.
27
+
28
+ Below is a GIF showing an example of how to use the library.
2
29
 
3
30
  ![example](https://github.com/user-attachments/assets/28316425-8302-453e-b238-0c732606e6a7)
4
31
 
5
- ```bash
6
- npm i @kakasoo/deep-strict-types
7
- ```
32
+ ## DeepStrictObjectKeys
8
33
 
9
- # DeepStrictTypes
34
+ `DeepStrictObjectKeys` extracts all keys from a nested object, preserving its hierarchical structure as a union of string paths.
35
+ That means you can access not only top-level keys but also nested keys using dot notation or, for arrays, using `[*]`.
10
36
 
11
- **DeepStrictTypes** extends TypeScript utility types, enabling safe operations like `Omit` and `Pick` on deeply nested objects or arrays by specifying keys to be inferred. It provides strict and accurate type checks, simplifying tasks like removing a single key from a nested object without recombining multiple types. Quickly and precisely omit or pick the internal keys you need!
37
+ ### Key Features
12
38
 
13
- ## Key Features
39
+ - **Preserves Hierarchy:** It retrieves every key from within an object so you can express paths like "user.address.city".
40
+ - **Accurate Type Inference:** Instead of just using `keyof`, it thoroughly infers every nested key for enhanced type safety.
41
+ - **Array Support:** For objects within arrays, it uses `[*]` instead of an index, so you cover all elements at once.
14
42
 
15
- ### `DeepStrictObjectKeys`
43
+ ### Example
16
44
 
17
- Extract all nested keys from an object `T`, preserving its structure. Useful for safely handling specific keys at deeper levels of an object.
45
+ The following example shows how to extract keys from a nested object using `DeepStrictObjectKeys`.
18
46
 
19
47
  ```typescript
20
48
  type Example = {
@@ -31,123 +59,304 @@ type Example = {
31
59
  type Keys = DeepStrictObjectKeys<Example>;
32
60
  ```
33
61
 
34
- Also, We create function for this type! Application of existing Object.keys to nested objects.
62
+ The library also offers a utility function `deepStrictObjectKeys` based on this type, which works like `Object.keys` but correctly extracts nested paths.
35
63
 
36
- ```ts
64
+ ```typescript
37
65
  type Target = { a: 1 }[][];
38
- const keys = deepStrictObjectKeys({} as Target); // "[*].[*].a"[]
66
+ const keys = deepStrictObjectKeys({} as Target); // Result: ["[*].[*].a"]
39
67
  ```
40
68
 
41
- In arrays, elements are represented with the `[*]` symbol, ensuring perfect inference even for nested structures.
69
+ ## DeepStrictOmit
70
+
71
+ `DeepStrictOmit` creates a new type by removing specified keys from a nested object type.
72
+ Similar to the built-in `Omit`, it lets you precisely specify key paths—even in nested structures and arrays—to remove unwanted properties.
73
+
74
+ ### Key Features
75
+
76
+ - **Omit Nested Keys:** You can specify a nested key path like `"user.profile.name"` to remove just that property.
77
+ - **Handles Arrays:** It applies the same logic to objects within arrays, so you can remove a key from every element.
78
+ - **Accurate Type Inference:** It preserves the rest of the object’s structure and types after omission.
79
+ - **Supports Branded Types:** It works safely with branded types, removing unnecessary constraints.
42
80
 
43
- ### `DeepStrictOmit`
81
+ ### Example
44
82
 
45
- Create a new type by excluding properties corresponding to key `K` from object `T`, preserving the nested structure.
83
+ Below is an example of how to apply `DeepStrictOmit` to both nested objects and objects within arrays.
46
84
 
47
85
  ```typescript
86
+ // Define an example object type
48
87
  type Example = {
49
88
  user: {
50
- name: string;
51
- age: number;
89
+ id: string;
90
+ profile: {
91
+ name: string;
92
+ age: number;
93
+ email: string;
94
+ };
95
+ posts: {
96
+ title: string;
97
+ content: string;
98
+ meta: {
99
+ likes: number;
100
+ shares: number;
101
+ };
102
+ }[];
52
103
  };
53
104
  };
54
105
 
55
- // Result: { user: { age: number; } }
56
- type Omitted = DeepStrictOmit<Example, 'user.name'>;
106
+ // Remove the keys 'user.profile.email' and 'user.posts[*].meta.shares'
107
+ type Omitted = DeepStrictOmit<Example, 'user.profile.email' | 'user.posts[*].meta.shares'>;
108
+
109
+ /*
110
+ Resulting type Omitted:
111
+ {
112
+ user: {
113
+ id: string;
114
+ profile: {
115
+ name: string;
116
+ age: number;
117
+ };
118
+ posts: {
119
+ title: string;
120
+ content: string;
121
+ meta: {
122
+ likes: number;
123
+ };
124
+ }[];
125
+ };
126
+ }
127
+ */
57
128
  ```
58
129
 
59
- This is particularly effective for branded types. Below is an example using the `typia` library:
130
+ In short, with `DeepStrictOmit` you can neatly remove only the keys you want from even the most complex nested objects or arrays.
60
131
 
61
- ```typescript
62
- test('Apply DeepStrictOmit to branding types', () => {
63
- type TestInterface = {
64
- id: string;
65
- thumbnails: {
66
- name: string & MinLength<1> & MaxLength<255>;
67
- url: string;
68
- }[];
69
- };
132
+ ## DeepStrictPick
70
133
 
71
- type Question = DeepStrictOmit<TestInterface, 'id'>;
72
- type IsAnswer = Equal<Question, { thumbnails: { name: string & MinLength<1> & MaxLength<255>; url: string }[] }>;
134
+ `DeepStrictPick` creates a new type by selecting only the specified keys from a nested object type.
135
+ It works like the built-in `Pick` but lets you precisely choose key paths—even in nested structures and arrays—so you only get the properties you need.
73
136
 
74
- ok(typia.random<IsAnswer>());
75
- });
76
- ```
137
+ ### Key Features
77
138
 
78
- ### `DeepStrictPick`
139
+ - **Pick Nested Keys:** Specify a nested key path like `"user.profile.name"` to pick only that property.
140
+ - **Handles Arrays:** It also works on objects within arrays, allowing you to extract just the desired data.
141
+ - **Accurate Type Inference:** It builds a type that only includes the selected properties, enhancing both type safety and readability.
142
+ - **Flexible:** You can specify multiple nested keys at once.
79
143
 
80
- Select properties corresponding to key `K` from object `T`, preserving the nested structure.
144
+ ### Example
145
+
146
+ Below is an example of using `DeepStrictPick` on nested objects and arrays.
81
147
 
82
148
  ```typescript
149
+ // Define an example object type
83
150
  type Example = {
84
151
  user: {
85
- name: string;
86
- age: number;
152
+ id: string;
153
+ profile: {
154
+ name: string;
155
+ age: number;
156
+ email: string;
157
+ };
158
+ posts: {
159
+ title: string;
160
+ content: string;
161
+ meta: {
162
+ likes: number;
163
+ shares: number;
164
+ };
165
+ }[];
87
166
  };
88
167
  };
89
168
 
90
- // Result: { user: { name: string; } }
91
- type Picked = DeepStrictPick<Example, 'user.name'>;
169
+ // Pick only the keys 'user.profile.name' and 'user.posts[*].meta.likes'
170
+ type Picked = DeepStrictPick<Example, 'user.profile.name' | 'user.posts[*].meta.likes'>;
171
+
172
+ /*
173
+ Resulting type Picked:
174
+ {
175
+ user: {
176
+ profile: {
177
+ name: string;
178
+ };
179
+ posts: {
180
+ meta: {
181
+ likes: number;
182
+ };
183
+ }[];
184
+ };
185
+ }
186
+ */
92
187
  ```
93
188
 
94
- ### `DeepStrictUnbrand`
189
+ So, `DeepStrictPick` lets you extract only the properties you want from even the most deeply nested structures.
95
190
 
96
- Remove branding from type `T`, even in deeply nested objects, simplifying the handling of branded types.
191
+ ## StringToDeepObject
97
192
 
98
- ```typescript
99
- type BrandedType = { value: number & { unit: 'dollar' } };
193
+ `StringToDeepObject` takes a string path in dot notation and generates a nested object type corresponding to that path.
194
+ It parses the path string step by step, building a nested object and assigning the desired type to the final property.
195
+
196
+ ### Key Features
197
+
198
+ - **Parses Path Strings:** Converts a string like "user.profile.name" into an object where each segment becomes a key.
199
+ - **Dynamically Creates Objects:** Automatically builds a nested object based on the path, assigning the specified type at the end.
200
+ - **Merges Union Types:** If you pass a union of path strings, it merges the resulting objects into one combined type.
201
+ - **Type Safe:** Handles string paths safely within the type system to accurately represent nested structures.
202
+
203
+ ### Example
100
204
 
101
- // Result: { value: number; }
102
- type Unbranded = DeepStrictUnbrand<BrandedType>;
205
+ ```typescript
206
+ // Example: Assigning a string type to the path 'user.profile.name'
207
+ type DeepObj = StringToDeepObject<'user.profile.name', string>;
208
+
209
+ /*
210
+ Resulting type DeepObj:
211
+ {
212
+ user: {
213
+ profile: {
214
+ name: string;
215
+ };
216
+ };
217
+ }
218
+ */
219
+
220
+ // Another example: Assigning a number type at the end of a path
221
+ type DeepNumberObj = StringToDeepObject<'settings.display.brightness', number>;
222
+
223
+ /*
224
+ Resulting type DeepNumberObj:
225
+ {
226
+ settings: {
227
+ display: {
228
+ brightness: number;
229
+ };
230
+ };
231
+ }
232
+ */
233
+
234
+ // Union type example: Two paths merge into one combined object type
235
+ type MergedObj = StringToDeepObject<'user.profile.name' | 'user.profile.age', string | number>;
236
+
237
+ /*
238
+ Resulting type MergedObj:
239
+ {
240
+ user: {
241
+ profile: {
242
+ name: string;
243
+ age: number;
244
+ };
245
+ };
246
+ }
247
+ */
103
248
  ```
104
249
 
105
- ### `GetType`
250
+ In short, `StringToDeepObject` lets you quickly create nested object types from a dot-delimited string, and even merge multiple paths if needed.
251
+
252
+ ## DeepStrictMerge
253
+
254
+ `DeepStrictMerge` deeply merges two or more object types into a single unified type.
255
+ It recursively combines every property in nested structures, and when the same key exists in multiple objects, it follows a set of rules to merge them.
256
+
257
+ ### Key Features
258
+
259
+ - **Deep Merge:** Recursively merges not only top-level properties but also all nested objects.
260
+ - **Accurate Type Inference:** Each object’s type information is retained in the merged result, ensuring type safety.
261
+ - **Conflict Resolution:** When the same key exists in multiple objects, it resolves the conflict according to defined rules.
262
+ - **Flexible:** You can merge several object types at once, making it easy to manage complex data structures.
106
263
 
107
- Get the type of a specific key path from a nested object type `T`. This is useful for extracting the type of deeply nested properties safely.
264
+ ### Example
108
265
 
109
266
  ```typescript
110
- type Example = {
267
+ // Define two object types to merge
268
+ type ObjA = {
111
269
  user: {
112
- name: string;
113
- address: {
114
- city: string;
115
- zip: number;
270
+ id: string;
271
+ profile: {
272
+ name: string;
273
+ age: number;
116
274
  };
117
275
  };
118
276
  };
119
277
 
120
- // Result: string
121
- type CityType = GetType<Example, 'user.address.city'>;
278
+ type ObjB = {
279
+ user: {
280
+ profile: {
281
+ email: string;
282
+ // If both objects have the key 'age', the merge rule applies.
283
+ age: number;
284
+ };
285
+ settings: {
286
+ theme: string;
287
+ };
288
+ };
289
+ };
122
290
 
123
- // Result: { city: string; zip: number; }
124
- type AddressType = GetType<Example, 'user.address'>;
291
+ // Deep merge the two objects into one type
292
+ type Merged = DeepStrictMerge<ObjA, ObjB>;
293
+
294
+ /*
295
+ Resulting type Merged:
296
+ {
297
+ user: {
298
+ id: string;
299
+ profile: {
300
+ name: string;
301
+ age: number; // Merged according to the rules
302
+ email: string;
303
+ };
304
+ settings: {
305
+ theme: string;
306
+ };
307
+ };
308
+ }
309
+ */
125
310
  ```
126
311
 
127
- ## Utility functions (Experimental)
312
+ So, `DeepStrictMerge` lets you seamlessly combine different object types into one, even when they have complex nested structures.
313
+
314
+ ## DeepDateToString
315
+
316
+ `DeepDateToString` finds every `Date` type in an object and converts it to a `string` recursively.
317
+ It locates all `Date` properties—even deep within nested objects or arrays—and converts them to strings, which is especially useful for serialization or JSON conversion.
318
+
319
+ ### Key Features
320
+
321
+ - **Recursive Conversion:** It transforms every `Date` type found in the object, including those in nested objects and arrays.
322
+ - **Ensures Type Consistency:** By explicitly converting `Date` to `string`, it prevents type mismatches during serialization or API responses.
323
+ - **Handles Complex Structures:** Works reliably even with deeply nested objects and arrays containing `Date` values.
128
324
 
129
- ### `DeepStrictAssert`
325
+ ### Example
130
326
 
131
327
  ```typescript
132
- interface Example {
133
- a: number;
134
- b: number;
135
- c: {
136
- d: string;
137
- e: string;
138
- f: {
139
- g: boolean;
140
- h: boolean;
328
+ // Define an example object type
329
+ type Example = {
330
+ createdAt: Date;
331
+ updatedAt: Date;
332
+ user: {
333
+ name: string;
334
+ birthDate: Date;
335
+ posts: {
336
+ title: string;
337
+ publishedAt: Date;
141
338
  }[];
142
- }[];
143
- }
144
-
145
- declare const E: Example;
339
+ };
340
+ };
146
341
 
147
- // Expected: { c: Array<{ d: string }> }
148
- const answer = deepStrictAssert(E)('c[*].d');
342
+ // Convert all Date properties to string using DeepDateToString
343
+ type StringifiedExample = DeepDateToString<Example>;
344
+
345
+ /*
346
+ Resulting type StringifiedExample:
347
+ {
348
+ createdAt: string;
349
+ updatedAt: string;
350
+ user: {
351
+ name: string;
352
+ birthDate: string;
353
+ posts: {
354
+ title: string;
355
+ publishedAt: string;
356
+ }[];
357
+ };
358
+ }
359
+ */
149
360
  ```
150
361
 
151
- ---
152
-
153
- This is just a part of the features provided by **DeepStrictTypes**, designed to enhance TypeScript's type manipulation capabilities and improve developer productivity. For more details, check out the library's full documentation.
362
+ In short, `DeepDateToString` makes sure that every `Date` inside an object is converted to a `string`, ensuring type consistency for operations like serialization or JSON conversion.
@@ -1,7 +1,6 @@
1
1
  import { DeepStrictObjectKeys } from '../types';
2
2
  type RemoveStartWithDot<T extends string> = T extends `.${infer R extends string}` ? R : T;
3
- type Replace<T extends string> = ReplaceWildcard<T>;
4
- type ReplaceWildcard<S extends string> = S extends '[*]' ? `${number}` : S extends `[*].${infer Rest}` ? `${number}.${ReplaceWildcard<Rest>}` : S extends `${infer Prefix extends string}.[*]${infer Rest}` ? `${Prefix}.${number}${ReplaceWildcard<Rest>}` : S extends `${infer Prefix extends string}[*]${infer Rest}` ? `${Prefix}.${number}${ReplaceWildcard<Rest>}` : S;
3
+ type Replace<S extends string> = S extends '[*]' ? `${number}` : S extends `[*].${infer Rest}` ? `${number}.${Replace<Rest>}` : S extends `${infer Prefix extends string}.[*]${infer Rest}` ? `${Prefix}.${number}${Replace<Rest>}` : S extends `${infer Prefix extends string}[*]${infer Rest}` ? `${Prefix}.${number}${Replace<Rest>}` : S;
5
4
  type ReturnType<Target extends object, Joiner extends {
6
5
  array: string;
7
6
  object: string;
@@ -1 +1 @@
1
- {"version":3,"file":"DeepStrictObjectKeys.d.ts","sourceRoot":"","sources":["../../../src/functions/DeepStrictObjectKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAEhD,KAAK,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;AAE3F,KAAK,OAAO,CAAC,CAAC,SAAS,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC;AAEpD,KAAK,eAAe,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,KAAK,GACpD,GAAG,MAAM,EAAE,GACX,CAAC,SAAS,OAAO,MAAM,IAAI,EAAE,GAC3B,GAAG,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,GACpC,CAAC,SAAS,GAAG,MAAM,MAAM,SAAS,MAAM,OAAO,MAAM,IAAI,EAAE,GACzD,GAAG,MAAM,IAAI,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE,GAC7C,CAAC,SAAS,GAAG,MAAM,MAAM,SAAS,MAAM,MAAM,MAAM,IAAI,EAAE,GACxD,GAAG,MAAM,IAAI,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE,GAC7C,CAAC,CAAC;AAEZ,KAAK,UAAU,CACb,MAAM,SAAS,MAAM,EACrB,MAAM,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,IAC9E,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAE/G,wBAAgB,oBAAoB,CAClC,MAAM,SAAS,MAAM,EACrB,MAAM,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,EAChF,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB5C"}
1
+ {"version":3,"file":"DeepStrictObjectKeys.d.ts","sourceRoot":"","sources":["../../../src/functions/DeepStrictObjectKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAEhD,KAAK,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;AAE3F,KAAK,OAAO,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,KAAK,GAC5C,GAAG,MAAM,EAAE,GACX,CAAC,SAAS,OAAO,MAAM,IAAI,EAAE,GAC3B,GAAG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,GAC5B,CAAC,SAAS,GAAG,MAAM,MAAM,SAAS,MAAM,OAAO,MAAM,IAAI,EAAE,GACzD,GAAG,MAAM,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,GACrC,CAAC,SAAS,GAAG,MAAM,MAAM,SAAS,MAAM,MAAM,MAAM,IAAI,EAAE,GACxD,GAAG,MAAM,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,GACrC,CAAC,CAAC;AAEZ,KAAK,UAAU,CACb,MAAM,SAAS,MAAM,EACrB,MAAM,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,IAC9E,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAE/G,wBAAgB,oBAAoB,CAClC,MAAM,SAAS,MAAM,EACrB,MAAM,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,EAChF,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB5C"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeepStrictObjectKeys.js","sourceRoot":"","sources":["../../../src/functions/DeepStrictObjectKeys.ts"],"names":[],"mappings":";;AAqBA,oDAwBC;AAxBD,SAAgB,oBAAoB,CAGlC,MAAc;IACd,IAAI,MAAM,GAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAY,CAAC;IAC7D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAY,CAAC;IACnD,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAEvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,KAAK,GAAI,MAAc,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBAChD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC;gBACzE,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAA+B,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"DeepStrictObjectKeys.js","sourceRoot":"","sources":["../../../src/functions/DeepStrictObjectKeys.ts"],"names":[],"mappings":";;AAmBA,oDAwBC;AAxBD,SAAgB,oBAAoB,CAGlC,MAAc;IACd,IAAI,MAAM,GAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAY,CAAC;IAC7D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAY,CAAC;IACnD,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAEvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,KAAK,GAAI,MAAc,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBAChD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC;gBACzE,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAA+B,CAAC;AACrE,CAAC"}
@@ -4,6 +4,13 @@ import type { IsAny } from './IsAny';
4
4
  import type { IsUnion } from './IsUnion';
5
5
  import type { ValueType } from './ValueType';
6
6
  declare namespace DeepStrictObjectKeys {
7
+ /**
8
+ * Internal helper type that recursively extracts all keys from nested objects
9
+ * @template Target - The object type to extract keys from
10
+ * @template Joiner - Defines the symbols used to join nested paths (array: '[*]', object: '.')
11
+ * @template IsSafe - Controls whether to explore union types that mix primitives and objects
12
+ * @template P - The current property keys being processed (excludes array methods)
13
+ */
7
14
  type Infer<Target extends object, Joiner extends {
8
15
  array: string;
9
16
  object: string;
@@ -33,6 +40,7 @@ export type DeepStrictObjectKeys<Target extends object, Joiner extends {
33
40
  } = {
34
41
  array: '[*]';
35
42
  object: '.';
36
- }, IsSafe extends boolean = true> = DeepStrictUnbrand<Target> extends Array<infer Element> ? IsAny<Element> extends true ? Joiner['array'] : Element extends object ? Joiner['array'] | `${Joiner['array']}.${DeepStrictObjectKeys<Element, Joiner, IsSafe>}` : Joiner['array'] : DeepStrictUnbrand<Target> extends readonly (infer Element)[] ? IsAny<Element> extends true ? Joiner['array'] : Element extends object ? Joiner['array'] | `${Joiner['array']}.${DeepStrictObjectKeys<Element, Joiner, IsSafe>}` : Joiner['array'] : DeepStrictObjectKeys.Infer<DeepStrictUnbrand<Target>, Joiner, IsSafe>;
43
+ }, IsSafe extends boolean = true> = DeepStrictUnbrand<Target> extends Array<infer Element> ? IsAny<Element> extends true ? Joiner['array'] : Element extends object ? // For arrays of objects, return both the array key and nested object keys
44
+ Joiner['array'] | `${Joiner['array']}.${DeepStrictObjectKeys<Element, Joiner, IsSafe>}` : Joiner['array'] : DeepStrictUnbrand<Target> extends readonly (infer Element)[] ? IsAny<Element> extends true ? Joiner['array'] : Element extends object ? Joiner['array'] | `${Joiner['array']}.${DeepStrictObjectKeys<Element, Joiner, IsSafe>}` : Joiner['array'] : DeepStrictObjectKeys.Infer<DeepStrictUnbrand<Target>, Joiner, IsSafe>;
37
45
  export {};
38
46
  //# sourceMappingURL=DeepStrictObjectKeys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DeepStrictObjectKeys.d.ts","sourceRoot":"","sources":["../../../src/types/DeepStrictObjectKeys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DeepStrictObjectKeys.d.ts","sourceRoot":"","sources":["../../../src/types/DeepStrictObjectKeys.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kakasoo/deep-strict-types",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "typescript utility types including deep-strict-omit and pick type",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -13,7 +13,7 @@
13
13
  "types": "bin/src/index.d.ts",
14
14
  "scripts": {
15
15
  "build": "rimraf bin && tsc",
16
- "build:test": "rimraf bin && tsc -p test/tsconfig.json --watch",
16
+ "build:test": "rimraf bin && tsc -p test/tsconfig.json",
17
17
  "prepare": "ts-patch install && typia patch",
18
18
  "test": "node bin/test/index.js",
19
19
  "prettier": "prettier src --write && prettier test --write"
@@ -47,6 +47,7 @@
47
47
  "author": "kakasoo",
48
48
  "license": "ISC",
49
49
  "devDependencies": {
50
+ "@nestia/e2e": "^7.3.0",
50
51
  "@samchon/shopping-api": "^0.14.1",
51
52
  "@types/inquirer": "^9.0.7",
52
53
  "@types/node": "^22.10.10",