3

I have the following type in typescript:

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

How can I drop all the empty properties (i.e. x and z) so that the resulting type will look like this?

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

2 Answers 2

1

With just your one example it's not clear which types other than literally {} you'd be okay with dropping: for example, do you need to keep or drop the object type? What about the unknown type? I'm not going to worry about this too much; just know that you should probably run through a suite of possible edge cases and figure out if the behavior of any type you come up with is acceptable.

Anyway, one possible implementation that doesn't rely on importing external libraries is:

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

This is using key remapping in mapped types to suppress any properties matching a certain criterion, by remapping the key in question to never.

You can verify that this behaves as desired for your example:

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

Playground link to code

Sign up to request clarification or add additional context in comments.

Comments

0

I found a solution, but it feels a bit verbose:

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

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

This produces the desired result:

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

Live example on codesandbox: https://codesandbox.io/s/drop-empty-properties-eu0l8

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.