My goal is to create a function that accepts an array of variables that can belong to a few different types
.
For each specified type
, the second argument (callback
) of the function will receive an array of corresponding types
.
The relationship is such that FooRequest
corresponds to Foo
, BarRequest
corresponds to Bar
, and so on.
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;
/**
* I am exploring how to define the callback `result` parameter to align with
* the counterpart types for each of the provided input types.
*
* For instance
* input: [{ _tag: 'foo' }, { _tag: 'bar' }]
* result type: [Foo, Bar]
*/
function makeArrayRequests<T extends AllRequests>(input: T[], callback: (result: ConditionalOutput<T>[]) => void) {
// additional logic here to trigger the callback can be implemented
}
makeArrayRequests([{ _tag: 'foo' }, { _tag: 'bar' }], ([a, b]) => {
// My desired outcome is for a to automatically be recognized as Foo and b as Bar
// However, currently both a and b are of type `Foo | Bar`
});