feat: generalize PartialDeep to TransformDeep

This commit is contained in:
gvergnaud
2023-02-28 20:53:42 +01:00
parent 51e3cfbaea
commit 07473723f9
2 changed files with 57 additions and 36 deletions

View File

@@ -384,24 +384,40 @@ export namespace Objects {
}
/**
* Makes all levels of an object partial
* @description This function is used to make all levels of an object partial
* @param obj - The object to make levels partial
* @returns The object with its levels made partial
* Makes all levels of an object optional
* @description This function is used to make all levels of an object optional
* @param obj - The object to make levels optional
* @returns The object with its levels made optional
*
* @example
* ```ts
* type T0 = Call<Objects.PartialDeep, {a: 1; b: true}>;
* // ^? {a?: 1; b?: true}
* type T1 = Call<Objects.PartialDeep, {a: 1; b: {c: true}}>;
* // ^? {a?: 1; b?: {c?: true}}
* type T2 = Call<Objects.PartialDeep, {a: 1; b: {c: true, d: {e: false}}}>;
* // ^? {a?: 1; b?: {c?: true, d?: {e?: false}}}
* ```
* type T0 = Call<Objects.PartialDeep, {a: 1; b: true }>; // { a?:1; b?: true}
* type T1 = Call<Objects.PartialDeep, {a: 1; b: { c: true } }>; // { a?:1; b?: { c?: true } }
* type T2 = Call<Objects.PartialDeep, {a: 1; b: { c: true, d: { e: false } } }>; // { a?:1; b?: { c?: true, d?: { e?: false } } }
*/
export type PartialDeep<obj = unset> = PartialApply<PartialDeepFn, [obj]>;
interface PartialDeepFn extends Fn {
return: this["args"] extends [infer obj] ? Impl.PartialDeep<obj> : never;
return: this["args"] extends [infer obj]
? Impl.TransformObjectDeep<PartialFn, obj>
: never;
}
export type RequiredDeep<obj = unset> = PartialApply<RequiredDeepFn, [obj]>;
interface RequiredDeepFn extends Fn {
return: this["args"] extends [infer obj]
? Impl.TransformObjectDeep<RequiredFn, obj>
: never;
}
export type ReadonlyDeep<obj = unset> = PartialApply<ReadonlyDeepFn, [obj]>;
interface ReadonlyDeepFn extends Fn {
return: this["args"] extends [infer obj]
? Impl.TransformObjectDeep<ReadonlyFn, obj>
: never;
}
/**

View File

@@ -65,31 +65,36 @@ type RecursiveGet<Obj, pathList> = Obj extends any
: Obj
: never;
export type PartialDeep<Type> = Type extends Function | Date
? Type
: Type extends Map<infer Keys, infer Values>
? Map<PartialDeep<Keys>, PartialDeep<Values>>
: Type extends ReadonlyMap<infer Keys, infer Values>
? ReadonlyMap<PartialDeep<Keys>, PartialDeep<Values>>
: Type extends WeakMap<infer Keys, infer Values>
? WeakMap<PartialDeep<Keys>, PartialDeep<Values>>
: Type extends Set<infer Values>
? Set<PartialDeep<Values>>
: Type extends ReadonlySet<infer Values>
? ReadonlySet<PartialDeep<Values>>
: Type extends WeakSet<infer Values>
? WeakSet<PartialDeep<Values>>
: Type extends Array<infer Values>
? IsTuple<Type> extends true
? { [Key in keyof Type]?: PartialDeep<Type[Key]> }
: Array<PartialDeep<Values> | undefined>
: Type extends Promise<infer Value>
? Promise<PartialDeep<Value>>
: Type extends object
? { [Key in keyof Type]?: PartialDeep<Type[Key]> }
: IsUnknown<Type> extends true
export type TransformObjectDeep<fn extends Fn, type> = type extends
| Function
| Date
? type
: type extends Map<infer keys, infer values>
? Map<TransformObjectDeep<fn, keys>, TransformObjectDeep<fn, values>>
: type extends ReadonlyMap<infer keys, infer values>
? ReadonlyMap<TransformObjectDeep<fn, keys>, TransformObjectDeep<fn, values>>
: type extends WeakMap<infer keys, infer values>
? WeakMap<
Extract<TransformObjectDeep<fn, keys>, object>,
TransformObjectDeep<fn, values>
>
: type extends Set<infer values>
? Set<TransformObjectDeep<fn, values>>
: type extends ReadonlySet<infer values>
? ReadonlySet<TransformObjectDeep<fn, values>>
: type extends WeakSet<infer values>
? WeakSet<Extract<TransformObjectDeep<fn, values>, object>>
: type extends Array<infer values>
? IsTuple<type> extends true
? Call<fn, { [Key in keyof type]: TransformObjectDeep<fn, type[Key]> }>
: Array<TransformObjectDeep<fn, values> | undefined>
: type extends Promise<infer value>
? Promise<TransformObjectDeep<fn, value>>
: type extends object
? Call<fn, { [Key in keyof type]: TransformObjectDeep<fn, type[Key]> }>
: IsUnknown<type> extends true
? unknown
: Partial<Type>;
: Partial<type>;
export type Update<obj, path, fnOrValue> = RecursiveUpdate<
obj,