ts-data-forge 1.0.0 → 1.0.2

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 (292) hide show
  1. package/README.md +1 -1
  2. package/dist/array/array-utils.d.mts +2617 -0
  3. package/dist/array/array-utils.d.mts.map +1 -0
  4. package/dist/array/array-utils.mjs +2915 -0
  5. package/dist/array/array-utils.mjs.map +1 -0
  6. package/dist/array/index.d.mts +3 -0
  7. package/dist/array/index.d.mts.map +1 -0
  8. package/dist/array/index.mjs +3 -0
  9. package/dist/array/index.mjs.map +1 -0
  10. package/dist/array/tuple-utils.d.mts +421 -0
  11. package/dist/array/tuple-utils.d.mts.map +1 -0
  12. package/dist/array/tuple-utils.mjs +391 -0
  13. package/dist/array/tuple-utils.mjs.map +1 -0
  14. package/dist/collections/imap-mapped.d.mts +445 -0
  15. package/dist/collections/imap-mapped.d.mts.map +1 -0
  16. package/dist/collections/imap-mapped.mjs +424 -0
  17. package/dist/collections/imap-mapped.mjs.map +1 -0
  18. package/dist/collections/imap.d.mts +359 -0
  19. package/dist/collections/imap.d.mts.map +1 -0
  20. package/dist/collections/imap.mjs +338 -0
  21. package/dist/collections/imap.mjs.map +1 -0
  22. package/dist/collections/index.d.mts +7 -0
  23. package/dist/collections/index.d.mts.map +1 -0
  24. package/dist/collections/index.mjs +7 -0
  25. package/dist/collections/index.mjs.map +1 -0
  26. package/dist/collections/iset-mapped.d.mts +576 -0
  27. package/dist/collections/iset-mapped.d.mts.map +1 -0
  28. package/dist/collections/iset-mapped.mjs +522 -0
  29. package/dist/collections/iset-mapped.mjs.map +1 -0
  30. package/dist/collections/iset.d.mts +426 -0
  31. package/dist/collections/iset.d.mts.map +1 -0
  32. package/dist/collections/iset.mjs +437 -0
  33. package/dist/collections/iset.mjs.map +1 -0
  34. package/dist/collections/queue.d.mts +190 -0
  35. package/dist/collections/queue.d.mts.map +1 -0
  36. package/dist/collections/queue.mjs +317 -0
  37. package/dist/collections/queue.mjs.map +1 -0
  38. package/dist/collections/stack.d.mts +210 -0
  39. package/dist/collections/stack.d.mts.map +1 -0
  40. package/dist/collections/stack.mjs +353 -0
  41. package/dist/collections/stack.mjs.map +1 -0
  42. package/dist/expect-type.d.mts +199 -0
  43. package/dist/expect-type.d.mts.map +1 -0
  44. package/dist/expect-type.mjs +201 -0
  45. package/dist/expect-type.mjs.map +1 -0
  46. package/dist/functional/index.d.mts +5 -0
  47. package/dist/functional/index.d.mts.map +1 -0
  48. package/dist/functional/index.mjs +5 -0
  49. package/dist/functional/index.mjs.map +1 -0
  50. package/dist/functional/match.d.mts +215 -0
  51. package/dist/functional/match.d.mts.map +1 -0
  52. package/dist/functional/match.mjs +139 -0
  53. package/dist/functional/match.mjs.map +1 -0
  54. package/dist/functional/optional.d.mts +517 -0
  55. package/dist/functional/optional.d.mts.map +1 -0
  56. package/dist/functional/optional.mjs +532 -0
  57. package/dist/functional/optional.mjs.map +1 -0
  58. package/dist/functional/pipe.d.mts +185 -0
  59. package/dist/functional/pipe.d.mts.map +1 -0
  60. package/dist/functional/pipe.mjs +129 -0
  61. package/dist/functional/pipe.mjs.map +1 -0
  62. package/dist/functional/result.d.mts +796 -0
  63. package/dist/functional/result.d.mts.map +1 -0
  64. package/dist/functional/result.mjs +844 -0
  65. package/dist/functional/result.mjs.map +1 -0
  66. package/dist/globals.d.mts +38 -0
  67. package/dist/guard/has-key.d.mts +100 -0
  68. package/dist/guard/has-key.d.mts.map +1 -0
  69. package/dist/guard/has-key.mjs +94 -0
  70. package/dist/guard/has-key.mjs.map +1 -0
  71. package/dist/guard/index.d.mts +8 -0
  72. package/dist/guard/index.d.mts.map +1 -0
  73. package/dist/guard/index.mjs +8 -0
  74. package/dist/guard/index.mjs.map +1 -0
  75. package/dist/guard/is-non-empty-string.d.mts +106 -0
  76. package/dist/guard/is-non-empty-string.d.mts.map +1 -0
  77. package/dist/guard/is-non-empty-string.mjs +108 -0
  78. package/dist/guard/is-non-empty-string.mjs.map +1 -0
  79. package/dist/guard/is-non-null-object.d.mts +105 -0
  80. package/dist/guard/is-non-null-object.d.mts.map +1 -0
  81. package/dist/guard/is-non-null-object.mjs +108 -0
  82. package/dist/guard/is-non-null-object.mjs.map +1 -0
  83. package/dist/guard/is-primitive.d.mts +146 -0
  84. package/dist/guard/is-primitive.d.mts.map +1 -0
  85. package/dist/guard/is-primitive.mjs +161 -0
  86. package/dist/guard/is-primitive.mjs.map +1 -0
  87. package/dist/guard/is-record.d.mts +151 -0
  88. package/dist/guard/is-record.d.mts.map +1 -0
  89. package/dist/guard/is-record.mjs +155 -0
  90. package/dist/guard/is-record.mjs.map +1 -0
  91. package/dist/guard/is-type.d.mts +430 -0
  92. package/dist/guard/is-type.d.mts.map +1 -0
  93. package/dist/guard/is-type.mjs +432 -0
  94. package/dist/guard/is-type.mjs.map +1 -0
  95. package/dist/guard/key-is-in.d.mts +158 -0
  96. package/dist/guard/key-is-in.d.mts.map +1 -0
  97. package/dist/guard/key-is-in.mjs +160 -0
  98. package/dist/guard/key-is-in.mjs.map +1 -0
  99. package/dist/index.d.mts +11 -0
  100. package/dist/index.d.mts.map +1 -0
  101. package/dist/index.mjs +61 -0
  102. package/dist/index.mjs.map +1 -0
  103. package/dist/iterator/index.d.mts +2 -0
  104. package/dist/iterator/index.d.mts.map +1 -0
  105. package/dist/iterator/index.mjs +2 -0
  106. package/dist/iterator/index.mjs.map +1 -0
  107. package/dist/iterator/range.d.mts +97 -0
  108. package/dist/iterator/range.d.mts.map +1 -0
  109. package/dist/iterator/range.mjs +130 -0
  110. package/dist/iterator/range.mjs.map +1 -0
  111. package/dist/json/index.d.mts +2 -0
  112. package/dist/json/index.d.mts.map +1 -0
  113. package/dist/json/index.mjs +2 -0
  114. package/dist/json/index.mjs.map +1 -0
  115. package/dist/json/json.d.mts +597 -0
  116. package/dist/json/json.d.mts.map +1 -0
  117. package/dist/json/json.mjs +687 -0
  118. package/dist/json/json.mjs.map +1 -0
  119. package/dist/number/branded-types/finite-number.d.mts +291 -0
  120. package/dist/number/branded-types/finite-number.d.mts.map +1 -0
  121. package/dist/number/branded-types/finite-number.mjs +296 -0
  122. package/dist/number/branded-types/finite-number.mjs.map +1 -0
  123. package/dist/number/branded-types/index.d.mts +27 -0
  124. package/dist/number/branded-types/index.d.mts.map +1 -0
  125. package/dist/number/branded-types/index.mjs +27 -0
  126. package/dist/number/branded-types/index.mjs.map +1 -0
  127. package/dist/number/branded-types/int.d.mts +242 -0
  128. package/dist/number/branded-types/int.d.mts.map +1 -0
  129. package/dist/number/branded-types/int.mjs +239 -0
  130. package/dist/number/branded-types/int.mjs.map +1 -0
  131. package/dist/number/branded-types/int16.d.mts +162 -0
  132. package/dist/number/branded-types/int16.d.mts.map +1 -0
  133. package/dist/number/branded-types/int16.mjs +141 -0
  134. package/dist/number/branded-types/int16.mjs.map +1 -0
  135. package/dist/number/branded-types/int32.d.mts +155 -0
  136. package/dist/number/branded-types/int32.d.mts.map +1 -0
  137. package/dist/number/branded-types/int32.mjs +142 -0
  138. package/dist/number/branded-types/int32.mjs.map +1 -0
  139. package/dist/number/branded-types/non-negative-finite-number.d.mts +165 -0
  140. package/dist/number/branded-types/non-negative-finite-number.d.mts.map +1 -0
  141. package/dist/number/branded-types/non-negative-finite-number.mjs +160 -0
  142. package/dist/number/branded-types/non-negative-finite-number.mjs.map +1 -0
  143. package/dist/number/branded-types/non-negative-int16.d.mts +160 -0
  144. package/dist/number/branded-types/non-negative-int16.d.mts.map +1 -0
  145. package/dist/number/branded-types/non-negative-int16.mjs +138 -0
  146. package/dist/number/branded-types/non-negative-int16.mjs.map +1 -0
  147. package/dist/number/branded-types/non-negative-int32.d.mts +156 -0
  148. package/dist/number/branded-types/non-negative-int32.d.mts.map +1 -0
  149. package/dist/number/branded-types/non-negative-int32.mjs +138 -0
  150. package/dist/number/branded-types/non-negative-int32.mjs.map +1 -0
  151. package/dist/number/branded-types/non-zero-finite-number.d.mts +154 -0
  152. package/dist/number/branded-types/non-zero-finite-number.d.mts.map +1 -0
  153. package/dist/number/branded-types/non-zero-finite-number.mjs +160 -0
  154. package/dist/number/branded-types/non-zero-finite-number.mjs.map +1 -0
  155. package/dist/number/branded-types/non-zero-int.d.mts +131 -0
  156. package/dist/number/branded-types/non-zero-int.d.mts.map +1 -0
  157. package/dist/number/branded-types/non-zero-int.mjs +128 -0
  158. package/dist/number/branded-types/non-zero-int.mjs.map +1 -0
  159. package/dist/number/branded-types/non-zero-int16.d.mts +166 -0
  160. package/dist/number/branded-types/non-zero-int16.d.mts.map +1 -0
  161. package/dist/number/branded-types/non-zero-int16.mjs +145 -0
  162. package/dist/number/branded-types/non-zero-int16.mjs.map +1 -0
  163. package/dist/number/branded-types/non-zero-int32.d.mts +158 -0
  164. package/dist/number/branded-types/non-zero-int32.d.mts.map +1 -0
  165. package/dist/number/branded-types/non-zero-int32.mjs +145 -0
  166. package/dist/number/branded-types/non-zero-int32.mjs.map +1 -0
  167. package/dist/number/branded-types/non-zero-safe-int.d.mts +148 -0
  168. package/dist/number/branded-types/non-zero-safe-int.d.mts.map +1 -0
  169. package/dist/number/branded-types/non-zero-safe-int.mjs +145 -0
  170. package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -0
  171. package/dist/number/branded-types/non-zero-uint16.d.mts +160 -0
  172. package/dist/number/branded-types/non-zero-uint16.d.mts.map +1 -0
  173. package/dist/number/branded-types/non-zero-uint16.mjs +140 -0
  174. package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -0
  175. package/dist/number/branded-types/non-zero-uint32.d.mts +156 -0
  176. package/dist/number/branded-types/non-zero-uint32.d.mts.map +1 -0
  177. package/dist/number/branded-types/non-zero-uint32.mjs +140 -0
  178. package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -0
  179. package/dist/number/branded-types/positive-finite-number.d.mts +171 -0
  180. package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -0
  181. package/dist/number/branded-types/positive-finite-number.mjs +165 -0
  182. package/dist/number/branded-types/positive-finite-number.mjs.map +1 -0
  183. package/dist/number/branded-types/positive-int.d.mts +270 -0
  184. package/dist/number/branded-types/positive-int.d.mts.map +1 -0
  185. package/dist/number/branded-types/positive-int.mjs +257 -0
  186. package/dist/number/branded-types/positive-int.mjs.map +1 -0
  187. package/dist/number/branded-types/positive-int16.d.mts +162 -0
  188. package/dist/number/branded-types/positive-int16.d.mts.map +1 -0
  189. package/dist/number/branded-types/positive-int16.mjs +139 -0
  190. package/dist/number/branded-types/positive-int16.mjs.map +1 -0
  191. package/dist/number/branded-types/positive-int32.d.mts +158 -0
  192. package/dist/number/branded-types/positive-int32.d.mts.map +1 -0
  193. package/dist/number/branded-types/positive-int32.mjs +139 -0
  194. package/dist/number/branded-types/positive-int32.mjs.map +1 -0
  195. package/dist/number/branded-types/positive-safe-int.d.mts +152 -0
  196. package/dist/number/branded-types/positive-safe-int.d.mts.map +1 -0
  197. package/dist/number/branded-types/positive-safe-int.mjs +138 -0
  198. package/dist/number/branded-types/positive-safe-int.mjs.map +1 -0
  199. package/dist/number/branded-types/positive-uint16.d.mts +160 -0
  200. package/dist/number/branded-types/positive-uint16.d.mts.map +1 -0
  201. package/dist/number/branded-types/positive-uint16.mjs +139 -0
  202. package/dist/number/branded-types/positive-uint16.mjs.map +1 -0
  203. package/dist/number/branded-types/positive-uint32.d.mts +156 -0
  204. package/dist/number/branded-types/positive-uint32.d.mts.map +1 -0
  205. package/dist/number/branded-types/positive-uint32.mjs +139 -0
  206. package/dist/number/branded-types/positive-uint32.mjs.map +1 -0
  207. package/dist/number/branded-types/safe-int.d.mts +243 -0
  208. package/dist/number/branded-types/safe-int.d.mts.map +1 -0
  209. package/dist/number/branded-types/safe-int.mjs +240 -0
  210. package/dist/number/branded-types/safe-int.mjs.map +1 -0
  211. package/dist/number/branded-types/safe-uint.d.mts +151 -0
  212. package/dist/number/branded-types/safe-uint.d.mts.map +1 -0
  213. package/dist/number/branded-types/safe-uint.mjs +138 -0
  214. package/dist/number/branded-types/safe-uint.mjs.map +1 -0
  215. package/dist/number/branded-types/uint.d.mts +144 -0
  216. package/dist/number/branded-types/uint.d.mts.map +1 -0
  217. package/dist/number/branded-types/uint.mjs +132 -0
  218. package/dist/number/branded-types/uint.mjs.map +1 -0
  219. package/dist/number/branded-types/uint16.d.mts +157 -0
  220. package/dist/number/branded-types/uint16.d.mts.map +1 -0
  221. package/dist/number/branded-types/uint16.mjs +137 -0
  222. package/dist/number/branded-types/uint16.mjs.map +1 -0
  223. package/dist/number/branded-types/uint32.d.mts +185 -0
  224. package/dist/number/branded-types/uint32.d.mts.map +1 -0
  225. package/dist/number/branded-types/uint32.mjs +169 -0
  226. package/dist/number/branded-types/uint32.mjs.map +1 -0
  227. package/dist/number/enum/index.d.mts +3 -0
  228. package/dist/number/enum/index.d.mts.map +1 -0
  229. package/dist/number/enum/index.mjs +3 -0
  230. package/dist/number/enum/index.mjs.map +1 -0
  231. package/dist/number/enum/int8.d.mts +202 -0
  232. package/dist/number/enum/int8.d.mts.map +1 -0
  233. package/dist/number/enum/int8.mjs +296 -0
  234. package/dist/number/enum/int8.mjs.map +1 -0
  235. package/dist/number/enum/uint8.d.mts +128 -0
  236. package/dist/number/enum/uint8.d.mts.map +1 -0
  237. package/dist/number/enum/uint8.mjs +251 -0
  238. package/dist/number/enum/uint8.mjs.map +1 -0
  239. package/dist/number/index.d.mts +5 -0
  240. package/dist/number/index.d.mts.map +1 -0
  241. package/dist/number/index.mjs +31 -0
  242. package/dist/number/index.mjs.map +1 -0
  243. package/dist/number/num.d.mts +515 -0
  244. package/dist/number/num.d.mts.map +1 -0
  245. package/dist/number/num.mjs +513 -0
  246. package/dist/number/num.mjs.map +1 -0
  247. package/dist/number/refined-number-utils.d.mts +191 -0
  248. package/dist/number/refined-number-utils.d.mts.map +1 -0
  249. package/dist/number/refined-number-utils.mjs +179 -0
  250. package/dist/number/refined-number-utils.mjs.map +1 -0
  251. package/dist/object/index.d.mts +2 -0
  252. package/dist/object/index.d.mts.map +1 -0
  253. package/dist/object/index.mjs +2 -0
  254. package/dist/object/index.mjs.map +1 -0
  255. package/dist/object/object.d.mts +296 -0
  256. package/dist/object/object.d.mts.map +1 -0
  257. package/dist/object/object.mjs +295 -0
  258. package/dist/object/object.mjs.map +1 -0
  259. package/dist/others/cast-mutable.d.mts +110 -0
  260. package/dist/others/cast-mutable.d.mts.map +1 -0
  261. package/dist/others/cast-mutable.mjs +114 -0
  262. package/dist/others/cast-mutable.mjs.map +1 -0
  263. package/dist/others/cast-readonly.d.mts +189 -0
  264. package/dist/others/cast-readonly.d.mts.map +1 -0
  265. package/dist/others/cast-readonly.mjs +193 -0
  266. package/dist/others/cast-readonly.mjs.map +1 -0
  267. package/dist/others/if-then.d.mts +98 -0
  268. package/dist/others/if-then.d.mts.map +1 -0
  269. package/dist/others/if-then.mjs +100 -0
  270. package/dist/others/if-then.mjs.map +1 -0
  271. package/dist/others/index.d.mts +8 -0
  272. package/dist/others/index.d.mts.map +1 -0
  273. package/dist/others/index.mjs +8 -0
  274. package/dist/others/index.mjs.map +1 -0
  275. package/dist/others/map-nullable.d.mts +151 -0
  276. package/dist/others/map-nullable.d.mts.map +1 -0
  277. package/dist/others/map-nullable.mjs +159 -0
  278. package/dist/others/map-nullable.mjs.map +1 -0
  279. package/dist/others/memoize-function.d.mts +173 -0
  280. package/dist/others/memoize-function.d.mts.map +1 -0
  281. package/dist/others/memoize-function.mjs +189 -0
  282. package/dist/others/memoize-function.mjs.map +1 -0
  283. package/dist/others/tuple.d.mts +159 -0
  284. package/dist/others/tuple.d.mts.map +1 -0
  285. package/dist/others/tuple.mjs +161 -0
  286. package/dist/others/tuple.mjs.map +1 -0
  287. package/dist/others/unknown-to-string.d.mts +180 -0
  288. package/dist/others/unknown-to-string.d.mts.map +1 -0
  289. package/dist/others/unknown-to-string.mjs +211 -0
  290. package/dist/others/unknown-to-string.mjs.map +1 -0
  291. package/dist/tsconfig.json +1 -0
  292. package/package.json +18 -16
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Casts a readonly type `T` to its `Mutable<T>` equivalent.
3
+ *
4
+ * **⚠️ Safety Warning**: This is a type assertion that bypasses TypeScript's immutability guarantees.
5
+ * The runtime value remains unchanged - only the type system's view of it changes.
6
+ * Use with caution as it can lead to unexpected mutations of data that was intended to be immutable.
7
+ *
8
+ * @template T - The type of the readonly value
9
+ * @param readonlyValue - The readonly value to cast to mutable
10
+ * @returns The same value with readonly modifiers removed from its type
11
+ *
12
+ * @example Basic usage with arrays and objects
13
+ * ```typescript
14
+ * const readonlyArr: readonly number[] = [1, 2, 3];
15
+ * const mutableArr = castMutable(readonlyArr);
16
+ * mutableArr.push(4); // Now allowed by TypeScript
17
+ *
18
+ * const readonlyObj: { readonly x: number } = { x: 1 };
19
+ * const mutableObj = castMutable(readonlyObj);
20
+ * mutableObj.x = 2; // Now allowed by TypeScript
21
+ * ```
22
+ *
23
+ * @example When to use - Working with third-party APIs
24
+ * ```typescript
25
+ * // Some APIs require mutable arrays but you have readonly data
26
+ * const readonlyData: readonly string[] = ['a', 'b', 'c'];
27
+ * const sortedData = castMutable([...readonlyData]); // Create a copy first!
28
+ * legacyApi.sort(sortedData); // API mutates the array
29
+ * ```
30
+ *
31
+ * @example Anti-pattern - Avoid mutating shared data
32
+ * ```typescript
33
+ * // ❌ Bad: Mutating data that other code expects to be immutable
34
+ * const sharedConfig: Readonly<Config> = getConfig();
35
+ * const mutable = castMutable(sharedConfig);
36
+ * mutable.apiKey = 'new-key'; // Dangerous! Other code expects this to be immutable
37
+ *
38
+ * // ✅ Good: Create a copy if you need to mutate
39
+ * const configCopy = castMutable({ ...sharedConfig });
40
+ * configCopy.apiKey = 'new-key'; // Safe - operating on a copy
41
+ * ```
42
+ *
43
+ * @see castDeepMutable - For deeply nested readonly structures
44
+ * @see castReadonly - For the opposite operation
45
+ */
46
+ export declare const castMutable: <T>(readonlyValue: T) => Mutable<T>;
47
+ /**
48
+ * Casts a readonly type `T` to its `DeepMutable<T>` equivalent, recursively removing all readonly modifiers.
49
+ *
50
+ * **⚠️ Safety Warning**: This recursively bypasses ALL immutability guarantees in nested structures.
51
+ * Extremely dangerous for complex data structures as it allows mutation at any depth.
52
+ * The runtime value is unchanged - only TypeScript's type checking is affected.
53
+ *
54
+ * @template T - The type of the deeply readonly value
55
+ * @param readonlyValue - The deeply readonly value to cast to deeply mutable
56
+ * @returns The same value with all readonly modifiers recursively removed from its type
57
+ *
58
+ * @example Basic usage with nested structures
59
+ * ```typescript
60
+ * const readonlyNested: {
61
+ * readonly a: { readonly b: readonly number[] }
62
+ * } = { a: { b: [1, 2, 3] } };
63
+ *
64
+ * const mutableNested = castDeepMutable(readonlyNested);
65
+ * mutableNested.a.b.push(4); // Mutations allowed at all levels
66
+ * mutableNested.a = { b: [5, 6] }; // Can replace entire objects
67
+ * mutableNested.a.b[0] = 99; // Can mutate array elements
68
+ * ```
69
+ *
70
+ * @example Practical use case - Working with immutable state updates
71
+ * ```typescript
72
+ * // When you need to perform multiple mutations before creating new immutable state
73
+ * const currentState: DeepReadonly<AppState> = getState();
74
+ * const draft = castDeepMutable(structuredClone(currentState)); // Clone first!
75
+ *
76
+ * // Perform multiple mutations on the draft
77
+ * draft.users.push(newUser);
78
+ * draft.settings.theme = 'dark';
79
+ * draft.data.items[0].completed = true;
80
+ *
81
+ * // Create new immutable state from the mutated draft
82
+ * const newState = castDeepReadonly(draft);
83
+ * setState(newState);
84
+ * ```
85
+ *
86
+ * @example Type complexity with generics
87
+ * ```typescript
88
+ * type DeepReadonlyUser = DeepReadonly<{
89
+ * id: number;
90
+ * profile: {
91
+ * settings: {
92
+ * preferences: string[];
93
+ * };
94
+ * };
95
+ * }>;
96
+ *
97
+ * function updateUserPreferences(user: DeepReadonlyUser, newPref: string) {
98
+ * // Create a mutable copy to work with
99
+ * const mutableUser = castDeepMutable(structuredClone(user));
100
+ * mutableUser.profile.settings.preferences.push(newPref);
101
+ * return castDeepReadonly(mutableUser);
102
+ * }
103
+ * ```
104
+ *
105
+ * @see castMutable - For shallow mutability casting
106
+ * @see castDeepReadonly - For the opposite operation
107
+ * @see structuredClone - Recommended for creating safe copies before mutation
108
+ */
109
+ export declare const castDeepMutable: <T>(readonlyValue: T) => DeepMutable<T>;
110
+ //# sourceMappingURL=cast-mutable.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cast-mutable.d.mts","sourceRoot":"","sources":["../../src/others/cast-mutable.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAG,eAAe,CAAC,KAAG,OAAO,CAAC,CAAC,CAC/B,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAG,eAAe,CAAC,KAAG,WAAW,CAAC,CAAC,CAEnC,CAAC"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Casts a readonly type `T` to its `Mutable<T>` equivalent.
3
+ *
4
+ * **⚠️ Safety Warning**: This is a type assertion that bypasses TypeScript's immutability guarantees.
5
+ * The runtime value remains unchanged - only the type system's view of it changes.
6
+ * Use with caution as it can lead to unexpected mutations of data that was intended to be immutable.
7
+ *
8
+ * @template T - The type of the readonly value
9
+ * @param readonlyValue - The readonly value to cast to mutable
10
+ * @returns The same value with readonly modifiers removed from its type
11
+ *
12
+ * @example Basic usage with arrays and objects
13
+ * ```typescript
14
+ * const readonlyArr: readonly number[] = [1, 2, 3];
15
+ * const mutableArr = castMutable(readonlyArr);
16
+ * mutableArr.push(4); // Now allowed by TypeScript
17
+ *
18
+ * const readonlyObj: { readonly x: number } = { x: 1 };
19
+ * const mutableObj = castMutable(readonlyObj);
20
+ * mutableObj.x = 2; // Now allowed by TypeScript
21
+ * ```
22
+ *
23
+ * @example When to use - Working with third-party APIs
24
+ * ```typescript
25
+ * // Some APIs require mutable arrays but you have readonly data
26
+ * const readonlyData: readonly string[] = ['a', 'b', 'c'];
27
+ * const sortedData = castMutable([...readonlyData]); // Create a copy first!
28
+ * legacyApi.sort(sortedData); // API mutates the array
29
+ * ```
30
+ *
31
+ * @example Anti-pattern - Avoid mutating shared data
32
+ * ```typescript
33
+ * // ❌ Bad: Mutating data that other code expects to be immutable
34
+ * const sharedConfig: Readonly<Config> = getConfig();
35
+ * const mutable = castMutable(sharedConfig);
36
+ * mutable.apiKey = 'new-key'; // Dangerous! Other code expects this to be immutable
37
+ *
38
+ * // ✅ Good: Create a copy if you need to mutate
39
+ * const configCopy = castMutable({ ...sharedConfig });
40
+ * configCopy.apiKey = 'new-key'; // Safe - operating on a copy
41
+ * ```
42
+ *
43
+ * @see castDeepMutable - For deeply nested readonly structures
44
+ * @see castReadonly - For the opposite operation
45
+ */
46
+ const castMutable = (readonlyValue) => readonlyValue;
47
+ /**
48
+ * Casts a readonly type `T` to its `DeepMutable<T>` equivalent, recursively removing all readonly modifiers.
49
+ *
50
+ * **⚠️ Safety Warning**: This recursively bypasses ALL immutability guarantees in nested structures.
51
+ * Extremely dangerous for complex data structures as it allows mutation at any depth.
52
+ * The runtime value is unchanged - only TypeScript's type checking is affected.
53
+ *
54
+ * @template T - The type of the deeply readonly value
55
+ * @param readonlyValue - The deeply readonly value to cast to deeply mutable
56
+ * @returns The same value with all readonly modifiers recursively removed from its type
57
+ *
58
+ * @example Basic usage with nested structures
59
+ * ```typescript
60
+ * const readonlyNested: {
61
+ * readonly a: { readonly b: readonly number[] }
62
+ * } = { a: { b: [1, 2, 3] } };
63
+ *
64
+ * const mutableNested = castDeepMutable(readonlyNested);
65
+ * mutableNested.a.b.push(4); // Mutations allowed at all levels
66
+ * mutableNested.a = { b: [5, 6] }; // Can replace entire objects
67
+ * mutableNested.a.b[0] = 99; // Can mutate array elements
68
+ * ```
69
+ *
70
+ * @example Practical use case - Working with immutable state updates
71
+ * ```typescript
72
+ * // When you need to perform multiple mutations before creating new immutable state
73
+ * const currentState: DeepReadonly<AppState> = getState();
74
+ * const draft = castDeepMutable(structuredClone(currentState)); // Clone first!
75
+ *
76
+ * // Perform multiple mutations on the draft
77
+ * draft.users.push(newUser);
78
+ * draft.settings.theme = 'dark';
79
+ * draft.data.items[0].completed = true;
80
+ *
81
+ * // Create new immutable state from the mutated draft
82
+ * const newState = castDeepReadonly(draft);
83
+ * setState(newState);
84
+ * ```
85
+ *
86
+ * @example Type complexity with generics
87
+ * ```typescript
88
+ * type DeepReadonlyUser = DeepReadonly<{
89
+ * id: number;
90
+ * profile: {
91
+ * settings: {
92
+ * preferences: string[];
93
+ * };
94
+ * };
95
+ * }>;
96
+ *
97
+ * function updateUserPreferences(user: DeepReadonlyUser, newPref: string) {
98
+ * // Create a mutable copy to work with
99
+ * const mutableUser = castDeepMutable(structuredClone(user));
100
+ * mutableUser.profile.settings.preferences.push(newPref);
101
+ * return castDeepReadonly(mutableUser);
102
+ * }
103
+ * ```
104
+ *
105
+ * @see castMutable - For shallow mutability casting
106
+ * @see castDeepReadonly - For the opposite operation
107
+ * @see structuredClone - Recommended for creating safe copies before mutation
108
+ */
109
+ const castDeepMutable = (readonlyValue) =>
110
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
111
+ readonlyValue;
112
+
113
+ export { castDeepMutable, castMutable };
114
+ //# sourceMappingURL=cast-mutable.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cast-mutable.mjs","sources":["../../src/others/cast-mutable.mts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CG;AACI,MAAM,WAAW,GAAG,CAAK,aAAgB,KAC9C;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DG;AACI,MAAM,eAAe,GAAG,CAAK,aAAgB;AAClD;AACA;;;;"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Casts a mutable type `T` to its `Readonly<T>` equivalent.
3
+ *
4
+ * This is a safe type assertion that adds immutability constraints at the type level.
5
+ * The runtime value remains unchanged - only TypeScript's view of it becomes readonly.
6
+ * This helps prevent accidental mutations and makes code intentions clearer.
7
+ *
8
+ * @template T - The type of the mutable value
9
+ * @param mutable - The mutable value to cast to readonly
10
+ * @returns The same value with readonly modifiers added to its type
11
+ *
12
+ * @example Basic usage with arrays and objects
13
+ * ```typescript
14
+ * const mutableArr: number[] = [1, 2, 3];
15
+ * const readonlyArr = castReadonly(mutableArr);
16
+ * // readonlyArr.push(4); // ❌ TypeScript Error: no 'push' on readonly array
17
+ *
18
+ * const mutableObj = { x: 1, y: 2 };
19
+ * const readonlyObj = castReadonly(mutableObj);
20
+ * // readonlyObj.x = 5; // ❌ TypeScript Error: cannot assign to readonly property
21
+ * ```
22
+ *
23
+ * @example Protecting function return values
24
+ * ```typescript
25
+ * // Prevent callers from mutating internal state
26
+ * class UserService {
27
+ * private users: User[] = [];
28
+ *
29
+ * getUsers(): readonly User[] {
30
+ * return castReadonly(this.users); // Callers can't mutate the array
31
+ * }
32
+ * }
33
+ *
34
+ * const service = new UserService();
35
+ * const users = service.getUsers();
36
+ * // users.push(newUser); // ❌ TypeScript prevents this
37
+ * ```
38
+ *
39
+ * @example Creating immutable configurations
40
+ * ```typescript
41
+ * // Start with mutable object for initialization
42
+ * const config = {
43
+ * apiUrl: 'https://api.example.com',
44
+ * timeout: 5000,
45
+ * retries: 3
46
+ * };
47
+ *
48
+ * // Validate and process config...
49
+ *
50
+ * // Export as readonly to prevent modifications
51
+ * export const APP_CONFIG = castReadonly(config);
52
+ * // APP_CONFIG.timeout = 10000; // ❌ TypeScript Error
53
+ * ```
54
+ *
55
+ * @example Working with array methods
56
+ * ```typescript
57
+ * const numbers: number[] = [1, 2, 3, 4, 5];
58
+ * const readonlyNumbers = castReadonly(numbers);
59
+ *
60
+ * // Read operations still work
61
+ * const doubled = readonlyNumbers.map(n => n * 2); // ✅ Returns new array
62
+ * const sum = readonlyNumbers.reduce((a, b) => a + b, 0); // ✅ Works
63
+ * const first = readonlyNumbers[0]; // ✅ Reading is allowed
64
+ *
65
+ * // Mutations are prevented
66
+ * // readonlyNumbers[0] = 10; // ❌ TypeScript Error
67
+ * // readonlyNumbers.sort(); // ❌ TypeScript Error (sort mutates)
68
+ * ```
69
+ *
70
+ * @see castDeepReadonly - For deeply nested structures
71
+ * @see castMutable - For the opposite operation (use with caution)
72
+ */
73
+ export declare const castReadonly: <T>(mutable: T) => Readonly<T>;
74
+ /**
75
+ * Casts a mutable type `T` to its `DeepReadonly<T>` equivalent, recursively adding readonly modifiers.
76
+ *
77
+ * This is a safe type assertion that adds immutability constraints at ALL levels of nesting.
78
+ * Provides complete protection against mutations in complex data structures.
79
+ * The runtime value is unchanged - only TypeScript's type checking is enhanced.
80
+ *
81
+ * @template T - The type of the mutable value
82
+ * @param mutable - The mutable value to cast to deeply readonly
83
+ * @returns The same value with readonly modifiers recursively added to all properties
84
+ *
85
+ * @example Basic usage with nested structures
86
+ * ```typescript
87
+ * const mutableNested = {
88
+ * a: { b: [1, 2, 3] },
89
+ * c: { d: { e: 'value' } }
90
+ * };
91
+ *
92
+ * const readonlyNested = castDeepReadonly(mutableNested);
93
+ * // readonlyNested.a.b.push(4); // ❌ Error: readonly at all levels
94
+ * // readonlyNested.c.d.e = 'new'; // ❌ Error: readonly at all levels
95
+ * // readonlyNested.a = {}; // ❌ Error: cannot reassign readonly property
96
+ * ```
97
+ *
98
+ * @example Protecting complex state objects
99
+ * ```typescript
100
+ * interface AppState {
101
+ * user: {
102
+ * id: number;
103
+ * profile: {
104
+ * name: string;
105
+ * settings: {
106
+ * theme: string;
107
+ * notifications: boolean[];
108
+ * };
109
+ * };
110
+ * };
111
+ * data: {
112
+ * items: Array<{ id: number; value: string }>;
113
+ * };
114
+ * }
115
+ *
116
+ * class StateManager {
117
+ * private state: AppState = initialState;
118
+ *
119
+ * getState(): DeepReadonly<AppState> {
120
+ * return castDeepReadonly(this.state);
121
+ * }
122
+ *
123
+ * // Mutations only allowed through specific methods
124
+ * updateTheme(theme: string) {
125
+ * this.state.user.profile.settings.theme = theme;
126
+ * }
127
+ * }
128
+ * ```
129
+ *
130
+ * @example Creating immutable API responses
131
+ * ```typescript
132
+ * async function fetchUserData(): Promise<DeepReadonly<UserData>> {
133
+ * const response = await api.get<UserData>('/user');
134
+ *
135
+ * // Process and validate data...
136
+ *
137
+ * // Return as deeply immutable to prevent accidental mutations
138
+ * return castDeepReadonly(response.data);
139
+ * }
140
+ *
141
+ * const userData = await fetchUserData();
142
+ * // userData is fully protected from mutations at any depth
143
+ * // userData.preferences.emails.push('new@email.com'); // ❌ TypeScript Error
144
+ * ```
145
+ *
146
+ * @example Working with Redux or state management
147
+ * ```typescript
148
+ * // Redux reducer example
149
+ * type State = DeepReadonly<AppState>;
150
+ *
151
+ * function reducer(state: State, action: Action): State {
152
+ * switch (action.type) {
153
+ * case 'UPDATE_USER_NAME':
154
+ * // Must create new objects, can't mutate
155
+ * return castDeepReadonly({
156
+ * ...state,
157
+ * user: {
158
+ * ...state.user,
159
+ * profile: {
160
+ * ...state.user.profile,
161
+ * name: action.payload
162
+ * }
163
+ * }
164
+ * });
165
+ * default:
166
+ * return state;
167
+ * }
168
+ * }
169
+ * ```
170
+ *
171
+ * @example Type inference with generics
172
+ * ```typescript
173
+ * function processData<T>(data: T): DeepReadonly<T> {
174
+ * // Perform processing...
175
+ * console.log('Processing:', data);
176
+ *
177
+ * // Return immutable version
178
+ * return castDeepReadonly(data);
179
+ * }
180
+ *
181
+ * const result = processData({ nested: { value: [1, 2, 3] } });
182
+ * // Type of result is DeepReadonly<{ nested: { value: number[] } }>
183
+ * ```
184
+ *
185
+ * @see castReadonly - For shallow readonly casting
186
+ * @see castDeepMutable - For the opposite operation (use with extreme caution)
187
+ */
188
+ export declare const castDeepReadonly: <T>(mutable: T) => DeepReadonly<T>;
189
+ //# sourceMappingURL=cast-readonly.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cast-readonly.d.mts","sourceRoot":"","sources":["../../src/others/cast-readonly.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAG,SAAS,CAAC,KAAG,QAAQ,CAAC,CAAC,CAChC,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiHG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAG,SAAS,CAAC,KAAG,YAAY,CAAC,CAAC,CAEpC,CAAC"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Casts a mutable type `T` to its `Readonly<T>` equivalent.
3
+ *
4
+ * This is a safe type assertion that adds immutability constraints at the type level.
5
+ * The runtime value remains unchanged - only TypeScript's view of it becomes readonly.
6
+ * This helps prevent accidental mutations and makes code intentions clearer.
7
+ *
8
+ * @template T - The type of the mutable value
9
+ * @param mutable - The mutable value to cast to readonly
10
+ * @returns The same value with readonly modifiers added to its type
11
+ *
12
+ * @example Basic usage with arrays and objects
13
+ * ```typescript
14
+ * const mutableArr: number[] = [1, 2, 3];
15
+ * const readonlyArr = castReadonly(mutableArr);
16
+ * // readonlyArr.push(4); // ❌ TypeScript Error: no 'push' on readonly array
17
+ *
18
+ * const mutableObj = { x: 1, y: 2 };
19
+ * const readonlyObj = castReadonly(mutableObj);
20
+ * // readonlyObj.x = 5; // ❌ TypeScript Error: cannot assign to readonly property
21
+ * ```
22
+ *
23
+ * @example Protecting function return values
24
+ * ```typescript
25
+ * // Prevent callers from mutating internal state
26
+ * class UserService {
27
+ * private users: User[] = [];
28
+ *
29
+ * getUsers(): readonly User[] {
30
+ * return castReadonly(this.users); // Callers can't mutate the array
31
+ * }
32
+ * }
33
+ *
34
+ * const service = new UserService();
35
+ * const users = service.getUsers();
36
+ * // users.push(newUser); // ❌ TypeScript prevents this
37
+ * ```
38
+ *
39
+ * @example Creating immutable configurations
40
+ * ```typescript
41
+ * // Start with mutable object for initialization
42
+ * const config = {
43
+ * apiUrl: 'https://api.example.com',
44
+ * timeout: 5000,
45
+ * retries: 3
46
+ * };
47
+ *
48
+ * // Validate and process config...
49
+ *
50
+ * // Export as readonly to prevent modifications
51
+ * export const APP_CONFIG = castReadonly(config);
52
+ * // APP_CONFIG.timeout = 10000; // ❌ TypeScript Error
53
+ * ```
54
+ *
55
+ * @example Working with array methods
56
+ * ```typescript
57
+ * const numbers: number[] = [1, 2, 3, 4, 5];
58
+ * const readonlyNumbers = castReadonly(numbers);
59
+ *
60
+ * // Read operations still work
61
+ * const doubled = readonlyNumbers.map(n => n * 2); // ✅ Returns new array
62
+ * const sum = readonlyNumbers.reduce((a, b) => a + b, 0); // ✅ Works
63
+ * const first = readonlyNumbers[0]; // ✅ Reading is allowed
64
+ *
65
+ * // Mutations are prevented
66
+ * // readonlyNumbers[0] = 10; // ❌ TypeScript Error
67
+ * // readonlyNumbers.sort(); // ❌ TypeScript Error (sort mutates)
68
+ * ```
69
+ *
70
+ * @see castDeepReadonly - For deeply nested structures
71
+ * @see castMutable - For the opposite operation (use with caution)
72
+ */
73
+ const castReadonly = (mutable) => mutable;
74
+ /**
75
+ * Casts a mutable type `T` to its `DeepReadonly<T>` equivalent, recursively adding readonly modifiers.
76
+ *
77
+ * This is a safe type assertion that adds immutability constraints at ALL levels of nesting.
78
+ * Provides complete protection against mutations in complex data structures.
79
+ * The runtime value is unchanged - only TypeScript's type checking is enhanced.
80
+ *
81
+ * @template T - The type of the mutable value
82
+ * @param mutable - The mutable value to cast to deeply readonly
83
+ * @returns The same value with readonly modifiers recursively added to all properties
84
+ *
85
+ * @example Basic usage with nested structures
86
+ * ```typescript
87
+ * const mutableNested = {
88
+ * a: { b: [1, 2, 3] },
89
+ * c: { d: { e: 'value' } }
90
+ * };
91
+ *
92
+ * const readonlyNested = castDeepReadonly(mutableNested);
93
+ * // readonlyNested.a.b.push(4); // ❌ Error: readonly at all levels
94
+ * // readonlyNested.c.d.e = 'new'; // ❌ Error: readonly at all levels
95
+ * // readonlyNested.a = {}; // ❌ Error: cannot reassign readonly property
96
+ * ```
97
+ *
98
+ * @example Protecting complex state objects
99
+ * ```typescript
100
+ * interface AppState {
101
+ * user: {
102
+ * id: number;
103
+ * profile: {
104
+ * name: string;
105
+ * settings: {
106
+ * theme: string;
107
+ * notifications: boolean[];
108
+ * };
109
+ * };
110
+ * };
111
+ * data: {
112
+ * items: Array<{ id: number; value: string }>;
113
+ * };
114
+ * }
115
+ *
116
+ * class StateManager {
117
+ * private state: AppState = initialState;
118
+ *
119
+ * getState(): DeepReadonly<AppState> {
120
+ * return castDeepReadonly(this.state);
121
+ * }
122
+ *
123
+ * // Mutations only allowed through specific methods
124
+ * updateTheme(theme: string) {
125
+ * this.state.user.profile.settings.theme = theme;
126
+ * }
127
+ * }
128
+ * ```
129
+ *
130
+ * @example Creating immutable API responses
131
+ * ```typescript
132
+ * async function fetchUserData(): Promise<DeepReadonly<UserData>> {
133
+ * const response = await api.get<UserData>('/user');
134
+ *
135
+ * // Process and validate data...
136
+ *
137
+ * // Return as deeply immutable to prevent accidental mutations
138
+ * return castDeepReadonly(response.data);
139
+ * }
140
+ *
141
+ * const userData = await fetchUserData();
142
+ * // userData is fully protected from mutations at any depth
143
+ * // userData.preferences.emails.push('new@email.com'); // ❌ TypeScript Error
144
+ * ```
145
+ *
146
+ * @example Working with Redux or state management
147
+ * ```typescript
148
+ * // Redux reducer example
149
+ * type State = DeepReadonly<AppState>;
150
+ *
151
+ * function reducer(state: State, action: Action): State {
152
+ * switch (action.type) {
153
+ * case 'UPDATE_USER_NAME':
154
+ * // Must create new objects, can't mutate
155
+ * return castDeepReadonly({
156
+ * ...state,
157
+ * user: {
158
+ * ...state.user,
159
+ * profile: {
160
+ * ...state.user.profile,
161
+ * name: action.payload
162
+ * }
163
+ * }
164
+ * });
165
+ * default:
166
+ * return state;
167
+ * }
168
+ * }
169
+ * ```
170
+ *
171
+ * @example Type inference with generics
172
+ * ```typescript
173
+ * function processData<T>(data: T): DeepReadonly<T> {
174
+ * // Perform processing...
175
+ * console.log('Processing:', data);
176
+ *
177
+ * // Return immutable version
178
+ * return castDeepReadonly(data);
179
+ * }
180
+ *
181
+ * const result = processData({ nested: { value: [1, 2, 3] } });
182
+ * // Type of result is DeepReadonly<{ nested: { value: number[] } }>
183
+ * ```
184
+ *
185
+ * @see castReadonly - For shallow readonly casting
186
+ * @see castDeepMutable - For the opposite operation (use with extreme caution)
187
+ */
188
+ const castDeepReadonly = (mutable) =>
189
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
190
+ mutable;
191
+
192
+ export { castDeepReadonly, castReadonly };
193
+ //# sourceMappingURL=cast-readonly.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cast-readonly.mjs","sources":["../../src/others/cast-readonly.mts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuEG;AACI,MAAM,YAAY,GAAG,CAAK,OAAU,KACzC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiHG;AACI,MAAM,gBAAgB,GAAG,CAAK,OAAU;AAC7C;AACA;;;;"}