utility-types icon indicating copy to clipboard operation
utility-types copied to clipboard

DeepPartial Improvement

Open Zomono opened this issue 8 months ago • 3 comments

Is your feature request related to a real problem or use-case?

I have two improvement ideas for the DeepPartial Type:

  1. DeepPartial currently makes all properties optional (?), but does not change the type definition of each property. A property that can be omitted should also include undefined in its type definition. This is useful, when you need to assign undefined explicitly to an optional property. With strictNullChecks enabled, the compiler currently raises an error if you try to assign undefined to an optional property where undefined is not included in its type definition.

  2. When I combine DeepPartial with DeepReadonly I get some errors on arrays. They are no longer iterable. DeepPartial currently treats ReadonlyArrays as objects and tries to make each property of the array partial. So my suggestion is to handle ReadonlyArray, ReadonlyMap and ReadonlySet properly in the implementiation of DeepPartial, like it is already done for the mutable versions of these collections.

Describe a solution including usage in code example

Here is my Solution for both suggestions. Feel free to include only one of my suggestions or none. I added a type parameter NIL in order to specify the nil-type that should be added to optional properties. This allows to also use null or to use never when the current behavior of DeepPartial is desired.

export type DeepPartial<T, NIL = undefined> =
    | T
    | (T extends Array<infer U>
          ? DeepPartial<U>[]
          : T extends ReadonlyArray<infer U>
            ? readonly DeepPartial<U>[]
            : T extends Map<infer K, infer V>
              ? Map<DeepPartial<K>, DeepPartial<V>>
              : T extends ReadonlyMap<infer K, infer V>
                ? ReadonlyMap<DeepPartial<K>, DeepPartial<V>>
                : T extends Set<infer M>
                  ? Set<DeepPartial<M>>
                  : T extends ReadonlySet<infer M>
                    ? ReadonlySet<DeepPartial<M>>
                    : T extends object
                      ? {
                            [K in keyof T]?: NIL | DeepPartial<T[K]>;
                        }
                      : T);

Who does this impact? Who is this for?

This feature is useful for all users of DeepPartial. Additionally, if you decide to pick NIL=never the current behavior is kept.

Zomono avatar Jun 26 '25 07:06 Zomono

Hey! Do you already have a PR open? If not, feel free to create one and link it here. Please add additional tests to ensure that both cases you described are fixed. Thanks!

piotrwitek avatar Jun 30 '25 06:06 piotrwitek

I have created a ticket within my customers company, but I cant tell when and if the tickets gets planned.

Zomono avatar Jul 04 '25 08:07 Zomono

Ticket has been rejected. Sorry.

Zomono avatar Oct 20 '25 14:10 Zomono