Closed
Description
TypeScript Version: 3.8.0-dev.20200119
Search Terms:
generic map
generic function union
Code
export interface Responses {
ping: {
pong: number;
};
status: {
status: string;
};
}
type ResponseTransformerMapping = {
[Action in keyof Responses]: (data: any) => Responses[Action];
};
export const ResponseTransformers: ResponseTransformerMapping = {
ping: (data): Responses['ping'] => ({
pong: data.pong,
}),
status: (data): Responses['status'] => ({
status: data.status,
}),
};
export const accessData = <Action extends keyof ResponseTransformerMapping>(
action: Action
): Responses[Action] => {
return ResponseTransformers[action]({});
};
Expected behavior:
Return type should be Responses[Action]
Actual behavior:
Return type is { pong: number; } | { status: string; }
Type '{ pong: number; } | { status: string; }' is not assignable to type 'Responses[Action]'.
Type '{ pong: number; }' is not assignable to type 'Responses[Action]'.
Type '{ pong: number; }' is not assignable to type '{ pong: number; } & { status: string; }'.
Property 'status' is missing in type '{ pong: number; }' but required in type '{ status: string; }'
Using return ResponseTransformers[action]({}) as Responses[Action];
works fine.
Playground Link: link
Related Issues:
Maybe #33014
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
RyanCavanaugh commentedon Feb 6, 2020
TS would need some higher-order reasoning to be able to detect that this code is correct. The problem is that
ResponseTransformerMapping
doesn't form any concrete connection between the key and the output type of the input key; we'd need to be able to establish that every possible call toResponseTransformerMapping[key]
results in a valid return type.LorenzHenk commentedon Feb 7, 2020
Isn't that enforced by
ResponseTransformerMapping
+ ensuring, that it's called with a valid key by using a generic?