【问题标题】: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

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

【问题讨论】:

    标签: typescript typescript3.0


    【解决方案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
    猜你喜欢
    • 2020-08-24
    • 1970-01-01
    • 2018-09-06
    • 2015-10-11
    • 2010-10-18
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2011-11-15
    相关资源
    最近更新 更多