исключите свойства с пустым типом объекта из типа в TypeScript

#typescript

Вопрос:

У меня есть следующий тип в машинописном тексте:

 type Foo = {
             x: {}; 
             y: {bar: string};
             z: {};
};
 

Как я могу удалить все пустые свойства (т. Е. x и z ), чтобы результирующий тип выглядел так?

 type Result = {
     y: {bar: string};
}
 

Ответ №1:

Только с одним вашим примером неясно, какие типы, кроме буквального {} , вы бы не возражали отказаться: например, вам нужно сохранить или удалить object тип? А как насчет этого unknown типа? Я не собираюсь слишком сильно беспокоиться об этом; просто знайте, что вам, вероятно, следует просмотреть набор возможных крайних случаев и выяснить, приемлемо ли поведение любого типа, которое вы придумали.

В любом случае, одной из возможных реализаций, которая не зависит от импорта внешних библиотек, является:

 type DropEmpty<T> =
  { [K in keyof T as keyof T[K] extends never ? never : K]: T[K] };
 

Это использование переназначения ключей в сопоставленных типах для подавления любых свойств, соответствующих определенному критерию, путем переназначения соответствующего ключа never .

Вы можете убедиться, что это работает так, как требуется для вашего примера:

 type Result = DropEmpty<Foo>
/*type Result = {
    y: {
        bar: string;
    };
} */
 

Ссылка на игровую площадку для кода

Ответ №2:

Я нашел решение, но оно кажется немного многословным:

 import type {ConditionalExcept} from 'type-fest';

type DropEmpty<T> = Pick<
  T,
  keyof ConditionalExcept<
    {
      [Property in keyof T]: keyof T[Property];
    },
    never
  >
>;
 

Это дает желаемый результат:

 type Foo = {
  x: {}; 
  y: {bar: string};
  z: {};
};
type Result = DropEmpty<Foo>;
 

Живой пример на codesandbox: https://codesandbox.io/s/drop-empty-properties-eu0l8