J'ai une union de deux types, dont l'un est un obj vide.

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

Je voudrais exclure l’objet vide de l’union, mais Exclude n’aide pas

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

J'ai essayé d'utiliser as const mais c'est le même résultat

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

L'ironie supplémentaire est que l'exclusion des autres propriétés est simple

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

TS Playground

Est-il donc possible d'exclure une interface vide d'autres interfaces dans une union?

3
lonewarrior556 24 avril 2020 à 17:04

2 réponses

Meilleure réponse

Répondre à ma propre question.

Si vous utilisez AtLeastOne de @lukasgeiter, répondez ici: Exclure l'objet vide du type Partial

Vous pouvez effectuer les opérations suivantes:

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
lonewarrior556 24 avril 2020 à 15:38

À partir de la documentation relative à la saisie conditionnelle ici, vous pouvez en fait attribuer des types en fonction de certaines conditions.

T extends U ? X : Y

Donc, pour la question ci-dessus, vous pouvez utiliser le mot clé keyof qui est utilisé pour extraire les clés des objets. Lorsqu'aucune clé n'a été trouvée, le type ne l'est jamais, nous pouvons vérifier si le keyof object ne s'étend jamais ou non, c'est-à-dire

 keyof K extends never

Donc, combiner le typage conditionnel ci-dessous;

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 }>

Vous pouvez enfin voir que ce type de U est un objet non vide, c'est-à-dire excluant un objet vide. Cochez cette aire de jeux

1
Dipesh Dulal 24 avril 2020 à 14:39