After consulting various responses to a specific question, I decided to construct my own interpretation of PartialDeep.
Throughout the process, I encountered difficulties with certain built-in objects. In my scenario, I would not anticipate a Date
object to be devoid of some of its essential methods. It should either be fully present or entirely absent.
Below is the customized version I devised:
// Primitive types (+ Date) are left as they are, or possibly undefined.
type PartialDeep<T> = T extends string | number | bigint | boolean | null | undefined | symbol | Date
? T | undefined
// Arrays, Sets, Maps, and their readonly counterparts have their inner elements partially modified, while maintaining the original instance structure
: T extends Array<infer ArrayType>
? Array<PartialDeep<ArrayType>>
: T extends ReadonlyArray<infer ArrayType>
? ReadonlyArray<ArrayType>
: T extends Set<infer SetType>
? Set<PartialDeep<SetType>>
: T extends ReadonlySet<infer SetType>
? ReadonlySet<SetType>
: T extends Map<infer KeyType, infer ValueType>
? Map<PartialDeep<KeyType>, PartialDeep<ValueType>>
: T extends ReadonlyMap<infer KeyType, infer ValueType>
? ReadonlyMap<PartialDeep<KeyType>, PartialDeep<ValueType>>
// ...and lastly, all other objects.
: {
[K in keyof T]?: PartialDeep<T[K]>;
};