Можно ли исключить пустой объект из объединения? - PullRequest
3 голосов
/ 24 апреля 2020

У меня есть объединение двух типов, один из которых является пустым объектом.

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

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

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Отвечая на мой собственный вопрос ..

Если вы используете AtLeastOne из @lukasgeiter, ответьте здесь: Исключить пустой объект из Частичного типа

, вы можете сделать следующее :

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

1 голос
/ 24 апреля 2020

Из документов для условного набора здесь вы можете назначать типы на основе некоторых условий.

T extends U ? X : Y

Итак, для вышеупомянутого вопроса вы можете использовать ключевое слово keyof, которое используется для извлечения ключей из объектов. Когда не найдено никаких ключей, тип никогда не бывает таким, мы можем проверить, расширяется ли keyof object никогда или нет, т.е. Наконец, вы можете увидеть, что тип U является непустым объектом, т.е. исключая пустой объект. Проверьте это детская площадка

...