I need to narrow down types based on dynamic keys:
type Responses = {http1: HttpResponse, http2: Http2Response};
const responses = {http1: {body,header}, http2: {body,header}};
const [bodies,headers]=(["body","header"] as const).map(field=>
Object.entries(responses).reduce((narrow,[key,value])=>
Object.assign(narrow,{[key]:value[field]}),
{} as {[key in keyof Responses]: responses[key][typeof field]})
);
// body = {http1: {body}, http2: {body}};
// header = {http1: {header}, http2: {header}};
but the value types end up being {http1: any, http2: any} instead of the respective Body and Header (not even Body|Header, even though that should be inferred by the indexed accesses, 'typeof field' being "body"|"header").
A simpler case would be simply inferring the type of mapped keys:
const [a,b]=(["body","header"] as const).map(field=>response[field]);
It results in union types (like Body|Header), instead of access types corresponding to the tuple indexes.
How to specify an indexed access type with dynamic keys?
Seems like an achievable inference, and would often spare a lot of redundant imperative declarations.