#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