Skip to content

Commit bc64de0

Browse files
authored
Merge pull request #60 from zuriscript:feature/minor-improvements
Support tuple types in Immutable<T> type definition
2 parents 65669bb + f240f79 commit bc64de0

File tree

3 files changed

+31
-17
lines changed

3 files changed

+31
-17
lines changed
Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
/* eslint-disable @typescript-eslint/no-unused-vars */
2+
/* eslint-disable @typescript-eslint/no-explicit-any */
13
/* eslint-disable @typescript-eslint/ban-types */
4+
25
/**
36
* Define a union type of built-in immutable primitives.
47
*/
@@ -14,24 +17,34 @@ type ImmutablePrimitive =
1417
| Date
1518
| RegExp;
1619

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+
1734
/**
1835
* Recursively transforms a given type into its deep readonly equivalent.
1936
* This transformation makes sure that the resulting type and its nested properties are immutable.
2037
*/
2138
export type Immutable<T> = T extends ImmutablePrimitive
2239
? 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>
2441
? 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.

packages/signalstory/src/lib/store-immutability/immutable-utility.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ export function naiveDeepClone<TState>(state: TState): TState {
1919
* @param {T} value - The value object to be cloned.
2020
* @returns {T} A deep clone of the provided value object.
2121
*/
22-
export const deepClone = <TState>(state: TState) =>
23-
window && 'structuredClone' in window
22+
export function deepClone<TState>(state: TState): TState {
23+
return window && 'structuredClone' in window
2424
? structuredClone(state)
2525
: naiveDeepClone(state);
26+
}
2627

2728
/**
2829
* Creates a shallow clone of a given value object

packages/signalstory/src/lib/store-mediator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function createRegistry(): MediatorRegistry {
2525
/**
2626
* Root mediator registry instance.
2727
*/
28-
export const rootRegistry: MediatorRegistry = createRegistry();
28+
export const rootRegistry: MediatorRegistry = /*@__PURE__*/ createRegistry();
2929

3030
/**
3131
* Register an event handler for a specific event.

0 commit comments

Comments
 (0)