Consider the following:
type U = {a: string, b: string};
type T = U & ({c: string, d?: never}|{c?: never, d: string});
type E = Exclude<T, {a: string}>;
type O = Omit<T, "a">;
const t1: T = {a: "a", b: "b", c: "c", d: "d"}; // error - expected
const t2: T = {a: "a", b: "b", c: "c"}; // ok - expected
const t3: T = {a: "a", b: "b", d: "d"}; // ok - expected
const e1: E = {b: "foo", c: "c", d: "d"}; // error - expected
const e2: E = {b: "foo", c: "c"}; // error: E is never
const e3: E = {b: "foo", d: "d"}; // error: E is never
const o1: O = {b: "foo", c: "c", d: "d"}; // ok - unexpected!
const o2: O = {b: "foo", c: "c"}; // ok
const o3: O = {b: "foo", d: "d"}; // ok
Type T
is defined as a object containing properties a
and b
and either c
or d
, but not both.
I am trying to construct a type that is identical to T
except it doesn’t have the a
property. I tried both Exclude
and Omit
, as it is evident from the above, neither gives me what I need.
Is there a way to remove a property from a black box type T
and keep everything else about it the same without knowing the structure of type T
in advance?
Also Typescript playground here.
Edit: Fixed the original type; added more test usages
Edit #2: This question is different from Typescript: Omit a property from all interfaces in a union, but keep the union structure because:
- The type in question is not a straight union but rather an intersection containing a union on one side
- It also addresses the issue of removing a property of from an arbitrary “black box” type without changing any other semantics of it.