Goal: make the return type of a function based upon the input type using a mapped type to lookup the return type.
Problem: I get an error because of the conflicts in intersection of discriminated union types, which I conceptually understand but am at a loss on how to structure my types to achieve the my goal.
Type 'Integration' is not assignable to type 'IntegrationTypeData[T]'.
Type 'IntegrationA' is not assignable to type 'IntegrationTypeData[T]'.
Type 'IntegrationA' is not assignable to type 'never'.
The intersection 'IntegrationA & IntegrationB' was reduced to 'never' because property 'name' has conflicting types in some constituents.
My type look like the following:
enum Integrations {
A = 'A',
B = 'B',
}
type IntegrationMap<M extends { [key: string]: any }> = {
[Key in keyof M]: M[Key]
};
type IntegrationA = {
name: Integrations.A,
propertyA: string;
}
type IntegrationB = {
name: Integrations.B,
propertyB: number;
}
type IntegrationData = {
[Integrations.A]: IntegrationA;
[Integrations.B]: IntegrationB;
};
// this resolves to type Integration = IntegrationA | IntegrationB
type Integration = IntegrationMap<IntegrationData>[keyof IntegrationMap<IntegrationData>];
// the function I want to make have a dynamic/mapped return type
const getIntegration = <T extends Integrations>(name: T): IntegrationData[T] => {
// the type of the integrations variable is Integration[]
const integration = integrations.find((i: Integration) => i.name === name);
return integration;
};
// desired usage
// typeof intB = IntegrationB
const intB = getIntegration(Integrations.B);
Can someone help me understand how to resolve this error and how to properly type the data so that I get a dynamic and type safe return type of this function?