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
Regression: Type using conditional and mapped types is no longer assignable in 4.3 #44092
Yep, like I suspected, this was caused by a change in inference. Namely, we used to erase local type parameters to any, while now we map them into their constraints. So in earlier versions of TS, we'd replace C with any, resolve the Pick into an object with some index signatures, and match up the index signature type S[any] against UnrollOnHover<S>[string] (getting S = UnrollOnHover<S>, same as the other inference site). Now, UnrollOnHover remains unexecuted, because C is only replaced with keyof S., so instead, we're matching {[k: string]: S[any]} to UnrollOnHover<Pick<UnrollOnHover<S>, keyof UnrollOnHover<S>>>, which, when we look at the mapped type in UnrollOnHover, looks like {[K in keyof Pick<UnrollOnHover<S>, keyof UnrollOnHover<S>>]: Pick<UnrollOnHover<S>, keyof UnrollOnHover<S>>[K]} and wouldn't ya know, that template matches up to the index signature type and we match S to Pick<UnrollOnHover<S>, keyof UnrollOnHover<S>>.
The new inference is definitely valid (certainly, it's an expression of the same type, even if we don't always recognize it as such) - it's an inference we always could have made (albeit with more contortions), it's just really unfortunate, since it's at the same priority as the other inference site (and last-in-wins). I have put up a PR (#44126) that lowers the priority of the secondary inference site in structures like this one, so the mapped-over structure is a lower priority than the plain type parameter, which gets back the old inference and thus assignability behavior.
Activity
weswigham commentedon May 17, 2021
Yep, like I suspected, this was caused by a change in inference. Namely, we used to erase local type parameters to
any, while now we map them into their constraints. So in earlier versions of TS, we'd replaceCwithany, resolve thePickinto an object with some index signatures, and match up the index signature typeS[any]againstUnrollOnHover<S>[string](gettingS = UnrollOnHover<S>, same as the other inference site). Now,UnrollOnHoverremains unexecuted, becauseCis only replaced withkeyof S., so instead, we're matching{[k: string]: S[any]}toUnrollOnHover<Pick<UnrollOnHover<S>, keyof UnrollOnHover<S>>>, which, when we look at the mapped type inUnrollOnHover, looks like{[K in keyof Pick<UnrollOnHover<S>, keyof UnrollOnHover<S>>]: Pick<UnrollOnHover<S>, keyof UnrollOnHover<S>>[K]}and wouldn't ya know, that template matches up to the index signature type and we matchStoPick<UnrollOnHover<S>, keyof UnrollOnHover<S>>.The new inference is definitely valid (certainly, it's an expression of the same type, even if we don't always recognize it as such) - it's an inference we always could have made (albeit with more contortions), it's just really unfortunate, since it's at the same priority as the other inference site (and last-in-wins). I have put up a PR (#44126) that lowers the priority of the secondary inference site in structures like this one, so the mapped-over structure is a lower priority than the plain type parameter, which gets back the old inference and thus assignability behavior.
dragomirtitian commentedon Jun 2, 2021
Daniel Rosenwasser (@DanielRosenwasser) Ryan Cavanaugh (@RyanCavanaugh) This does not appear fixed in 4.3.2 (Playground Link) but works in nightly (Playground Link). Will there be a 4.3.3 where this will be included ?