With TS 2.8 and conditional types we can simply write:
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends Array<infer U>
? Array<DeepPartial<U>>
: T[P] extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: DeepPartial<T[P]>
};
or with [] instead of Array<> that would be:
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends (infer U)[]
? DeepPartial<U>[]
: T[P] extends Readonly<infer U>[]
? Readonly<DeepPartial<U>>[]
: DeepPartial<T[P]>
};
You might want to checkout https://github.com/krzkaczor/ts-essentials package for this and some other useful types.