You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fresh object literal typed through satisfies and mapped type lose the origin informationΒ #52995
typeMyMap={"move-forward": {distance: number};stop: {cause: string};};typeValues<T>=T[keyofT];typeUnion<PextendskeyofMyMap=keyofMyMap>=Values<{[KinP]: {type: K}&MyMap[K];}>;// const action: { [K in keyof MyMap]: (move: MyMap[K]) => void } = {// "move-forward": (move) =>// console.log("Moving forward by distance:", move.distance),// stop: (move) => console.log("Stopping. Cause:", move.cause),// };constaction={"move-forward": (move)=>console.log("Moving forward by distance:",move.distance),stop: (move)=>console.log("Stopping. Cause:",move.cause),}satisfies{[KinkeyofMyMap]: (move: MyMap[K])=>void};functionexecute<KextendskeyofMyMap>(move: Union<K>){action[move.type](move);// errors but it should be OK just like the variant with the declared type}
π Actual behavior
It errors on the action[move.type](move) call within the generic function.
π Expected behavior
It should be OK just like the variant with the declared type.
When the type of action is known to be a mapped type, we can take a smarter analysis of action[move.type](move) to realize that the call is OK by analyzing the mapping rather than the possible concrete instantiations of K.
When it isn't, the only way to "see" that this call is OK is by brute enumeration of all possible inhabitants of K, which in general is not feasible from a performance perspective.
So in this case, we have to trade a little bit of completeness for a big gain in performance.
Cross-linking with #47109, which describes the working technique specifically as a way of dealing with the compiler's inability to efficiently scry into the multiverse of possible narrowings.
Yeah, so I know about this limitation. This issue is specifically about the satisfies. Here, the type is contextually typed through the satisfies operator and the mapped type is involved in creating this type. Therefore TS wouldn't have to figure out this relationship from scratch - it could be preserved on some link or something and utilized by the checker.
The eternal war between "TypeScript should always behave simply and consistently, even if it's a little bit worse" and "You can gerrymander in a little bit of logic to make things work when they otherwise wouldn't have" rages on.
Activity
RyanCavanaugh commentedon Feb 27, 2023
When the type of
actionis known to be a mapped type, we can take a smarter analysis ofaction[move.type](move)to realize that the call is OK by analyzing the mapping rather than the possible concrete instantiations ofK.When it isn't, the only way to "see" that this call is OK is by brute enumeration of all possible inhabitants of
K, which in general is not feasible from a performance perspective.So in this case, we have to trade a little bit of completeness for a big gain in performance.
jcalz commentedon Feb 27, 2023
Cross-linking with #47109, which describes the working technique specifically as a way of dealing with the compiler's inability to efficiently scry into the multiverse of possible narrowings.
RyanCavanaugh commentedon Feb 27, 2023
Thanks jcalz, I can never find that one when I need to π
Andarist commentedon Feb 27, 2023
Yeah, so I know about this limitation. This issue is specifically about the
satisfies. Here, the type is contextually typed through thesatisfiesoperator and the mapped type is involved in creating this type. Therefore TS wouldn't have to figure out this relationship from scratch - it could be preserved on some link or something and utilized by the checker.RyanCavanaugh commentedon Feb 28, 2023
The eternal war between "TypeScript should always behave simply and consistently, even if it's a little bit worse" and "You can gerrymander in a little bit of logic to make things work when they otherwise wouldn't have" rages on.
fatcerberus commentedon Feb 28, 2023
...so shut up and put on your poncho. You're in the splash zone. π
github-actions commentedon Jun 8, 2023
This issue has been marked as 'Not a Defect' and has seen no recent activity. It has been automatically closed for house-keeping purposes.