My goal is to define a type union where one of the types extends an existing type:
// The original type
type Foo<V> = { value: V; onChange: (value: V) => void };
// Type union incorporating Foo
type ADT = ({ kind: "foo" } & Foo<any>) | { kind: "bar" };
// Function that accepts this type union
function adt(adt: ADT) {}
The issue lies with Foo<any>
, which sets V
equal to any
and makes the type of onChange
's value also any
:
adt({ kind: "foo", value: 1, onChange: (value) => {
// value is any
}});
I am looking for a solution like:
type ADT = ({ kind: "foo" } & Foo<infer V> | { kind: "bar" };
Unfortunately, I cannot use the infer
syntax outside of an extends
clause.
Furthermore, I do not want to explicitly declare V
on ADT
itself as
ADT<V></code because the type of <code>V</code (and the number of inferences) depends on the specific type union being used. For instance:</p>
<pre><code>type ADT =
| ({ kind: "foo" } & Foo<infer V>)
| ({ kind: "bar" & Bar<infer A, infer B> });
Each member of the type union has distinct/inferred types.
Is there a way to achieve this?
Thank you!