Используйте Partial в вложенном свойстве с помощью typescript

Скажем, у меня есть такой тип:

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

Я делаю State Partial следующим образом Partial<State>

Но как я могу внести вложенные свойства частично, например, если бы я хотел сделать two также частичным.

Как мне это сделать?

Ответ 1

Вы можете легко определить свой собственный тип RecursivePartial, который сделает все свойства, включая вложенные, необязательными:

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

Если вы хотите, чтобы некоторые из ваших свойств были частичными, вы можете использовать это с пересечением и Pick:

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

Это сделает все необязательным, за исключением ключей, указанных в параметре K.

Ответ 2

Это возможно, вы можете создать "глубокий" частичный тип:

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

Который может использоваться как последовательный

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

Ответ 3

Для TypeScript 2.8 или более поздней версии следующий тип должен решить проблему со свойством Array.

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

Пожалуйста, посмотрите пример ниже.

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

Допустимый результат с условным типом

Valid Result

Неверный результат

Invalid Result

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

Ответ 4

Попробуйте исключить вложенное свойство и снова добавить его как частичное:

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