Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DeepExclude #184

Open
Sytten opened this issue Nov 11, 2020 · 8 comments
Open

DeepExclude #184

Sytten opened this issue Nov 11, 2020 · 8 comments
Labels
enhancement New feature or request

Comments

@Sytten
Copy link

Sytten commented Nov 11, 2020

Sometimes you just want to remove a type from all keys. A DeepExclude would be useful, something like:

type DeepExclude<T, I> = T extends Builtin
  ? Exclude<T, I>
  : T extends Map<infer K, infer V>
  ? Map<DeepExclude<K, I>, DeepExclude<V, I>>
  : T extends WeakMap<infer K, infer V>
  ? WeakMap<DeepExclude<K, I>, DeepExclude<V, I>>
  : T extends Set<infer U>
  ? Set<DeepExclude<U, I>>
  : T extends WeakSet<infer U>
  ? WeakSet<DeepExclude<U, I>>
  : T extends Array<infer U>
  ? T extends IsTuple<T>
    ? { [K in keyof T]: DeepExclude<T[K], I> }
    : Array<DeepExclude<U, I>>
  : T extends Promise<infer U>
  ? Promise<DeepExclude<U, I>>
  : T extends {}
  ? { [K in keyof T]: DeepExclude<T[K], I> }
  : Exclude<T, I>
@domoritz
Copy link

I would love to have a DeepExclude. The above type doesn't seem to quite work yet.

type O = DeepExclude<{foo: number | {bar: number}}, {bar: number}>;
type O = {
    foo: number | {
        bar: number;
    };
}

@Sytten
Copy link
Author

Sytten commented Nov 18, 2020

Interesting, I did not consider that use case. It works for us on simple cases like a class or an interface.

@domoritz
Copy link

I already use a mapped exclude type in my project but haven't figured out how to make it fully recursive yet. I'd be curious if you come up with a recursive version that works for arrays and interfaces.

export type MappedExclude<T, E> = {
  [P in keyof T]: Exclude<T[P], E>;
};

@domoritz
Copy link

domoritz commented Nov 19, 2020

I asked on SO and this solution works well for me: https://stackoverflow.com/a/64900252/214950.

type DeepExclude<T, U> =
  T extends U ? never :
  T extends object ? {
    [K in keyof T]: DeepExclude<T[K], U>
  } : T;

@Sytten
Copy link
Author

Sytten commented Nov 19, 2020

This only works for simple objects and it wont work for arrays, sets, promises, etc.

@domoritz
Copy link

It does work for arrays, actually.

Screen Shot 2020-11-19 at 12 53 38

@Beraliv Beraliv added the enhancement New feature or request label Aug 15, 2021
@Beraliv
Copy link
Collaborator

Beraliv commented May 1, 2024

Hey @Sytten! Do you still find DeepExclude valuable for yourself?

@Sytten
Copy link
Author

Sytten commented May 1, 2024

I dont work with typescript anymore, so for you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants