I have this function definition:
function example<
O extends { property: P; required: boolean },
P extends string
>(
arr: O[]
): {
[P in O["property"]]: O["required"] extends true
? string
: string | undefined;
};
example([
{ property: "hey", required: true },
{ property: "ho", required: false },
]);
Which gives this typing:
function example<{
property: "hey";
required: true;
} | {
property: "ho";
required: false;
}, string>(arr: ({
property: "hey";
required: true;
} | {
property: "ho";
required: false;
})[]): {
hey: string | undefined;
ho: string | undefined;
}
required: true should mean that the returned object definitely has the associated property, and required: false should mean it may or may not have it, i.e. string | undefined.
So hey should just be string in this scenario, as required is true.
If required is true for both of them, it types them both correctly as just string, but if one is false then it seems to widen the type for every key/value.
Is it possible to map types individually this way?