I have a few interfaces defined like so:
interface A {
toRemove: string;
key1: "this1";
key2: number;
}
interface B {
toRemove: string;
key1: "this2";
key3: string;
}
And a union of both interfaces:
type C = A|B;
What I want to do is to remove the toRemove
key from both interfaces through C, something like this:
type CC = Omit<A, "toRemove">|Omit<B, "toRemove">;
But without having to omit the key from both interfaces. This would be ideal:
type CC = Omit<C, "toRemove">;
But, unfortunately, CC
will be of type Pick<A|B, "key1">
, where key1
is the key present in both interfaces.
In essence, what I'm trying to achieve is a type of "function" to transform:
A1|A2|...|An
into:
Omit<A1, K keyof A1>|Omit<A1, K keyof A2>|...|Omit<An, K keyof An>
I came across this answer and I have a feeling that part of what I need is somewhere in there, but I don't really understand what's going on in that code.
You want to distribute the Omit
across a union. Luckily, you can use distributive conditional types to achieve this:
type DistributiveOmit<T, K extends keyof any> = T extends any
? Omit<T, K>
: never;
The T extends any
construction looks like it doesn't do much, but since T
is a type parameter, it distributes the conditional type across any union constituents of T
.
Let's test it:
type CC = DistributiveOmit<C, "toRemove">;
// type CC = Pick<A, "key1" | "key2"> | Pick<B, "key1" | "key3">
You can verify that this is equivalent to the CC
type you want.