Deep partials are incredibly useful. For very, very narrow use cases. For instance, if you're in a test file, writing a unit test or something, and you have an entity that you want to mock. Let's say it's a Post.


interface Post {

id: string

comments: { value: string }[]

meta: {

name: string

description: string

}

}


You don't really want to have to go in and manually fill out every field, including the comments array, every single time. Usually what you want to do is just provide just enough data to make the test run.

So what you can do there is you can use a deep partial for this.

Now, TypeScript does give you a Partial. But, if you were to wrap Post in just a Partial, you would still have to manually fill out all of the nested data since Partial only works one layer deep.


const post: Partial<Post> = {

id: "1",

meta: {

description: "123",

name: "123",

},

}


So a deep partial actually goes and makes every layer inside a Partial. So we don't have to provide a value to comments or meta for example.


const post: Partial<Post> = {

id: "1",

comments: [{}],

meta: {},

}


Again, this is very useful for very narrow use cases. Let's break down how it works. We have a DeepPartial that has a Thing. If Thing returns a function then we just return the Thing, because there's nothing to make partial there.

If our Thing extends an array and we infer the InferredArrayMember, then we use DeepPartialArray, which basically just calls DeepPartial on the thing inside it.

Otherwise, if Thing is an object, we use DeepPartialObject, which goes through each unrequired key in Thing and makes a DeepPartial of the value.


type DeepPartial<Thing> = Thing extends Function

? Thing

: Thing extends Array<infer InferredArrayMember>

? DeepPartialArray<InferredArrayMember>

: Thing extends object

? DeepPartialObject<Thing>

: Thing | undefined

interface DeepPartialArray<Thing> extends Array<DeepPartial<Thing>> {}

type DeepPartialObject<Thing> = {

[Key in keyof Thing]?: DeepPartial<Thing[Key]>

}


So you can see how it just recursively goes down and creates partials.