Home > database >  Omit properties that extends a specific type
Omit properties that extends a specific type

Time:12-17

Given the following interface:

interface Entity {
  A: boolean;
  B: string;
  C: number;
  D: never
}

I would like to create a type that omits the properties that extends never. Something like that:

type FilteredEntity = OmitNever<Entity>; //  = { A: boolean; B: string; C: number };

How OmitNever should be implemented?

CodePudding user response:

Here is how I would solve your problem:

interface Entity {
  A: boolean;
  B: string;
  C: number;
  D: never
}

type Entries<T> = {
  [K in keyof T]: [K, T[K]]
}[keyof T]

type EntriesWithValueOfType<T, U> = T extends [any, U] ? T : never;

type EntityNeverEntries = EntriesWithValueOfType<Entries<Entity>, never>

type KeysOfEntries<T> = T extends [infer U, any] ? U : never;

type OmitNever = Omit<Entity, KeysOfEntries<EntityNeverEntries>>

TypeScript playground

CodePudding user response:

I think you need something like this

// Omit a single property:
type FilteredEntity = Omit<Entity, "D">;
// Equivalent to: {A: boolean, B: string, C: number}

And for never

type Keys_NeverExcluded<T> = 
  { [K in keyof T]: T[K] extends never ? never : K }[keyof T]
type FilteredEntity = Pick<Entity, Keys_NeverExcluded<Entity>>

Now, if you tried something like

const p: FilteredEntity = {A: true, B: "test", C: 3, D: null}

It will tell you

Type '{ A: true; B: string; C: number; D: null; }' is not assignable to type 'FilteredEntity'.
  Object literal may only specify known properties, and 'D' does not exist in type 'FilteredEntity'.

Playground: https://tsplay.dev/wg6qlW

  • Related