是否可以从联合中排除空对象?

Posted

技术标签:

【中文标题】是否可以从联合中排除空对象?【英文标题】:Is it possible to Exclude an empty object from a union? 【发布时间】:2020-08-08 03:17:22 【问题描述】:

我有两种类型的并集,其中一种是空 obj。

type U =  |  a: number  // |  b: string  |  c: boolean  ....

我想从联合中排除空对象但是Exclude 没有帮助

type A = Exclude<U, >
// A = never

我尝试使用as const,但结果相同

const empty =  as const
type Empty = typeof empty
type U = Empty |  a: number 
type A = Exclude<U, Empty>
//type A = never

额外的讽刺是排除其他属性很简单

  type B = Exclude<U,  a: number >
  // type B = 

TS Playground

那么是否可以从联合中的其他接口中排除一个空接口?

【问题讨论】:

【参考方案1】:

从条件输入文档here,您实际上可以根据某些条件分配类型。

T extends U ? X : Y

所以对于上面的问题,你可以做的是使用keyof 关键字来从对象中提取键。当没有找到任何类型的键时,我们可以检查 keyof object 是否从不扩展,即

 keyof K extends never

所以结合下面的条件输入;

const empty =  as const
type Empty = typeof empty

type NoEmpty<K> = keyof K extends never ? never : K;

type C = NoEmpty<Empty>;

type U = NoEmpty<Empty> | NoEmpty< a: number >

你终于可以看到 U 的类型是非空对象,即不包括空对象。检查这个playground

【讨论】:

如果你不控制 decaring U 类型你将如何包装联合的所有部分【参考方案2】:

回答我自己的问题..

如果您使用来自@lukasgeiter 的AtLeastOne,请在此处回答:Exclude empty object from Partial type

您可以执行以下操作:

type AtLeastOne<T, U = [K in keyof T]: Pick<T, K> > = Partial<T> & U[keyof U];
    
type ExcludeEmpty<T> = T extends AtLeastOne<T> ? T : never; 
    
type U =  |  a: number  |  b: string 
    
type Foo = ExcludeEmpty<U> //  a: number  |  b: string 

TSplayground

【讨论】:

这是一个很好的解决方案:D

以上是关于是否可以从联合中排除空对象?的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌套对象的联合上的 LINQ to Entities 空引用

JavaScriptSerializer 可以排除具有空值/默认值的属性吗?

判断是否一个对象为空对象

空对象模式

从 mysql 选择中排除空数据

如何判断一个值是不是在list中