在typescript中使用嵌套属性中的Partial

时间:2017-12-20 21:22:17

标签: typescript

说我有这样的类型;

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

我将状态部署为Partial<State>

但是我如何才能使嵌套属性成为局部,例如,如果我想使two也是部分的。

我该怎么做?

5 个答案:

答案 0 :(得分:28)

您可以非常轻松地定义自己的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参数中指定的键,这将使之外的所有内容都可选。

答案 1 :(得分:8)

这是可能的,你可以创建一个深层次的&#39;部分类型如下:

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

可以按照以下方式使用

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

答案 2 :(得分: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

答案 3 :(得分:0)

尝试排除嵌套的属性,然后再次将其添加为“部分”:

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

答案 4 :(得分:0)

当您不想在基本类型中使用递归时,它可能很有用。


type RecursivePartial<T> = {
  [P in keyof T]?: typeof T[P] extends Record<string, unknown> ? RecursivePartial<T[P]> : T[P];
};