fluidstate
Version:
Library for fine-grained reactivity state management
244 lines (243 loc) • 7.74 kB
TypeScript
/**
* Options for configuring the behavior of the `cloneInert` function.
*/
export type CloneInertOptions = {
/**
* Whether the clone is deep.
* @default true
*/
deep?: boolean;
/**
* Whether computed property values should be excluded from the clone
* @default false
*/
excludeComputed?: boolean;
};
type IfEquals<X, Y, A = X, B = never> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? A : B;
/**
* This utility helps us extract only writable keys of an object, which is currently
* the best way to detect non-computed keys
*/
type WritableKeys<T> = {
[P in keyof T]-?: IfEquals<{
[Q in P]: T[P];
}, {
-readonly [Q in P]: T[P];
}, P>;
}[keyof T];
type CloneInertReadonlyTupleResult<T, Options extends CloneInertOptions, DepthLimit extends number, DepthTracker extends unknown[]> = T extends readonly [
infer T1,
infer T2,
infer T3,
infer T4,
infer T5,
infer T6
] ? readonly [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T5, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T6, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends readonly [infer T1, infer T2, infer T3, infer T4, infer T5] ? readonly [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T5, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends readonly [infer T1, infer T2, infer T3, infer T4] ? readonly [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends readonly [infer T1, infer T2, infer T3] ? readonly [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends readonly [infer T1, infer T2] ? readonly [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends readonly [infer T1] ? readonly [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>
] : undefined;
type CloneInertTupleResult<T, Options extends CloneInertOptions, DepthLimit extends number, DepthTracker extends unknown[]> = T extends [infer T1, infer T2, infer T3, infer T4, infer T5, infer T6] ? [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T5, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T6, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends [infer T1, infer T2, infer T3, infer T4, infer T5] ? [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T5, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends [infer T1, infer T2, infer T3, infer T4] ? [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends [infer T1, infer T2, infer T3] ? [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends [infer T1, infer T2] ? [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>,
CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [
0,
...DepthTracker
]>
] : T extends [infer T1] ? [
CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [
0,
...DepthTracker
]>
] : undefined;
type CloneInertResultWithDepthLimit<T, Options extends CloneInertOptions, DepthLimit extends number, DepthTracker extends unknown[]> = Options extends {
excludeComputed: true;
} ? DepthTracker["length"] extends DepthLimit ? T : CloneInertTupleResult<T, Options, DepthLimit, DepthTracker> extends {} ? CloneInertTupleResult<T, Options, DepthLimit, DepthTracker> : CloneInertReadonlyTupleResult<T, Options, DepthLimit, DepthTracker> extends {} ? CloneInertReadonlyTupleResult<T, Options, DepthLimit, DepthTracker> : T extends Map<infer Key, infer Value> ? Map<CloneInertResultWithDepthLimit<Key, Options, DepthLimit, [
0,
...DepthTracker
]>, CloneInertResultWithDepthLimit<Value, Options, DepthLimit, [
0,
...DepthTracker
]>> : T extends Set<infer Item> ? Set<CloneInertResultWithDepthLimit<Item, Options, DepthLimit, [
0,
...DepthTracker
]>> : T extends Array<infer Item> ? Array<CloneInertResultWithDepthLimit<Item, Options, DepthLimit, [
0,
...DepthTracker
]>> : T extends ReadonlyArray<infer Item> ? ReadonlyArray<CloneInertResultWithDepthLimit<Item, Options, DepthLimit, [
0,
...DepthTracker
]>> : T extends object ? {
[K in WritableKeys<T>]: CloneInertResultWithDepthLimit<T[K], Options, DepthLimit, [
0,
...DepthTracker
]>;
} : T : T;
export type CloneInertResult<T, Options extends CloneInertOptions> = Options extends {
deep: false;
} ? CloneInertResultWithDepthLimit<T, Options, 1, []> : CloneInertResultWithDepthLimit<T, Options, 15, []>;
export {};