从界面属性中删除空值

时间:2019-11-20 12:42:57

标签: typescript

我有一些描述深层对象结构的接口。像这样:

interface IBar {
  a: string | null;
  b: number | null;
}

interface IBaz {
  c: string | null;
  d: boolean | null;
}

interface IFoo {
  bar: IBar;
  baz: IBaz;
}

当前,对于每个属性,我正在使用非空断言运算符,例如obj.bar.a!。为了避免在需要访问属性的任何地方执行此操作,我想一种方法来创建一个新界面,该界面从“叶”界面中“删除” null

换句话说,我想做:

const obj: DoMagic<IFoo> = getObj();

使类型变为:

{
  bar: {
    a: string;
    b: number;
  },
  baz: {
    c: string;
    d: boolean;
  }
}

到目前为止,我只找到了DeepPartial的解决方案,我认为这与我所需要的完全相反。 NonNullable似乎相关,但我想将其应用于根接口,而不是应用于每个叶子。这可能吗?

1 个答案:

答案 0 :(得分:3)

可以使用mapped typesNonNullable类型的实用程序。

一个级别深版本:

type NoNullFields<Ob> = { [K in keyof Ob]: NonNullable<Ob[K]> };
type NoNullIBar = NoNullFields<IBar>;

NoNullFields 类型构造函数正在创建一种类型,该类型的键与给定的[K in keyof Ob]具有相同的键,但是值被null排除了NonNullable<Ob[K]>可能性的类型< / p>


递归版本(适用于嵌套结构)

type NoNullFields<Ob> = { [K in keyof Ob]: Ob[K] extends object 
? NoNullFields<Ob[K]> : NonNullable<Ob[K]> };
type NoNullIBar = NoNullFields<IBar>;

这部分最重要-Ob[K] extends object ? NoNullFields<Ob[K]> : NonNullable<Ob[K]>。这意味着如果该字段是一个对象,那么我们将在其上递归使用类型构造函数,如果不是,则将字段设置为NonNullable。