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