1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
3
/* eslint-disable @typescript-eslint/ban-types */
4
+
2
5
/**
3
6
* Define a union type of built-in immutable primitives.
4
7
*/
@@ -14,24 +17,34 @@ type ImmutablePrimitive =
14
17
| Date
15
18
| RegExp ;
16
19
20
+ /**
21
+ * Checks if a given type is a tuple.
22
+ */
23
+ type IsTuple < Type > = Type extends readonly any [ ]
24
+ ? any [ ] extends Type
25
+ ? never
26
+ : Type
27
+ : never ;
28
+
29
+ // Type wrappers for regular and readonly built-in container types
30
+ type AnyArray < T = any > = Array < T > | ReadonlyArray < T > ;
31
+ type AnySet < T = any > = Set < T > | ReadonlySet < T > ;
32
+ type AnyMap < TKey = any , TVal = any > = Map < TKey , TVal > | ReadonlyMap < TKey , TVal > ;
33
+
17
34
/**
18
35
* Recursively transforms a given type into its deep readonly equivalent.
19
36
* This transformation makes sure that the resulting type and its nested properties are immutable.
20
37
*/
21
38
export type Immutable < T > = T extends ImmutablePrimitive
22
39
? T // If the type is an immutable primitive, return it as is.
23
- : T extends Map < infer Keys , infer Values >
40
+ : T extends AnyMap < infer Keys , infer Values >
24
41
? ReadonlyMap < Immutable < Keys > , Immutable < Values > >
25
- : T extends ReadonlyMap < infer Keys , infer Values >
26
- ? ReadonlyMap < Immutable < Keys > , Immutable < Values > >
27
- : T extends Set < infer Values >
28
- ? ReadonlySet < Immutable < Values > >
29
- : T extends ReadonlySet < infer Values >
30
- ? ReadonlySet < Immutable < Values > >
31
- : T extends Array < infer Values >
32
- ? ReadonlyArray < Immutable < Values > >
33
- : T extends ReadonlyArray < infer Values >
34
- ? ReadonlyArray < Immutable < Values > >
35
- : T extends object
36
- ? { readonly [ Key in keyof T ] : Immutable < T [ Key ] > } // Recursively transform object properties.
37
- : Readonly < T > ; // For other types, return them as Readonly to make them immutable.
42
+ : T extends AnySet < infer Values >
43
+ ? ReadonlySet < Immutable < Values > >
44
+ : T extends AnyArray < infer Values >
45
+ ? T extends IsTuple < T >
46
+ ? { readonly [ Key in keyof T ] : Immutable < T [ Key ] > }
47
+ : ReadonlyArray < Immutable < Values > >
48
+ : T extends object
49
+ ? { readonly [ Key in keyof T ] : Immutable < T [ Key ] > } // Recursively transform object properties.
50
+ : Readonly < T > ; // For other types, return them as Readonly to make them immutable.
0 commit comments