Рекурсивный частичный <t> в TypeScript 2.1

У меня есть этот интерфейс:

export interface UserSettings
{
    one: {
        three: number;
        four: number;
    };
    two: {
        five: number;
        six: number;
    };
}

... и хочу превратить это в это:

export interface UserSettingsForUpdate
{
    one?: {
        three?: number;
        four?: number;
    };
    two?: {
        five?: number;
        six?: number;
    };
}

... но Partial<UserSettings> создает следующее:

{
    one?: {
        three: number;
        four: number;
    };
    two?: {
        five: number;
        six: number;
    };
}

Можно ли использовать сопоставленные типы, чтобы сделать все свойства на всех глубинах необязательными, или мне нужно создать для этого интерфейс вручную?

Ответ 1

При посадке условных типов в 2.8 мы можем теперь объявить рекурсивный частичный тип следующим образом.

type RecursivePartial<T> = {
  [P in keyof T]?:
    T[P] extends (infer U)[] ? RecursivePartial<U>[] :
    T[P] extends object ? RecursivePartial<T[P]> :
    T[P];
};

Справка:

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

Ответ 2

вы можете создать свой собственный тип отображения, например:

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

enter image description here

К сожалению, это не работает для полей с массивом. Кажется, что пока не существует способа отображения условного типа; т.е. предел примитивам. См. Https://github.com/Microsoft/TypeScript/pull/12114#issuecomment-259776847 Теперь это возможно, см. Другой ответ.