use Partial in nested property with typescript

Say I have a type like this;

interface State {
  one: string,
  two: {
    three: {
      four: string
    },
    five: string
  }
}

I make state Partial like this Partial<State>

But how can I make on of the nested properties partial, for example if I wanted to make two also partial.

How would I do this?


Solution 1:

You can pretty easily define your own RecursivePartial type, which will make all properties, included nested ones, optional:

type RecursivePartial<T> = {
    [P in keyof T]?: RecursivePartial<T[P]>;
};

If you only want some of your properties to be partial, then you can use this with an intersection and Pick:

type PartialExcept<T, K extends keyof T> = RecursivePartial<T> & Pick<T, K>;

That would make everything optional except for the keys specified in the K parameter.

Solution 2:

This is possible, you can create a 'deep' partial type as followed:

type DeepPartial<T> = {
    [P in keyof T]?: DeepPartial<T[P]>;
};

Which can be used as followed

const state: DeepPartial<State> = {
    two: {
        three: {
            four: '4'
        }
    }
}

Solution 3:

Array properties on Objects

For TypeScript 2.8 or later, the following type should fix problem about Array property:

type NestedPartial<T> = {
    [K in keyof T]?: T[K] extends Array<infer R> ? Array<NestedPartial<R>> : NestedPartial<T[K]>
};

Please see the example below.

interface Foo {
    NumProp: number;
    SubItem: Foo;
    SubItemArray: Foo[];
}

Valid Result with conditional type

Valid Result

Invalid Result

Invalid Result

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

Solution 4:

Try to exclude the nested Property, and add it again as Partial:

interface Foo {
    someName: Partial<Omit<MainType, 'lvl2Partial'> & { lvl2Partial: Partial<SubType> }>
}