What I want to do, is have a function which takes an array of variables which can be one of a few types
.
For each given type
, the function's second argument (callback
) will take an array of the counterpart types
FooRequest
will map to Foo
, BarRequest
, to Bar
, etc.
type FooRequest = {
_tag: 'foo',
}
type BarRequest = {
_tag: 'bar',
}
type DurRequest = {
_tag: 'dur',
}
type AllRequests = FooRequest | BarRequest | DurRequest;
type Foo = { t: 'foo', age: number };
type Bar = { t: 'bar', name: string };
type Dur = { t: 'dur', date: Date };
// chained conditional type mapping each "request" type to it's counterpart "result" type
type ConditionalOutput<T extends AllRequests> =
T extends FooRequest ? Foo :
T extends BarRequest ? Bar :
T extends DurRequest ? Dur : never;
/**
* How do I define the callback `result` parameter so it's an array matching
* the counterpart types for each of the given input types?
*
* For example
* input: [{ _tag: 'foo' }, { _tag: 'bar' }]
* result type: [Foo, Bar]
*/
function makeArrayRequests<T extends AllRequests>(input: T[], callback: (result: ConditionalOutput<T>[]) => void) {
// not part of the quesiton, but logic here to call the callback
}
makeArrayRequests([{ _tag: 'foo' }, { _tag: 'bar' }], ([a, b]) => {
// I want a to be auto infered to be Foo and b to be Bar
// but right now both a and b are `Foo | Bar`
});