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
Wrong types inferred and false-positive ts(2783) when spreading object literals with "inline" __proto__ #45580
NOTE: None of the flags I have set in that link matter or influence the result, they are simply some flags I like.
Please note that all the properties involved in this example are (AFAIK) statically known (to the extent reasonably possible, including as const for objects). Even so, the wrong types are inferred.
The bug
One compiler error (2783) and one explainer/hint message appear when hovering over the single squiggly line.
'proto' is specified more than once, so this usage will be overwritten.(2783)
This spread always overwrites this property.
Both are in fact wrong (in this special case, specifically involving __proto__ in object literals).
To the best of my knowledge, spreading could never overwrite a __proto__ declared "inline" (in the same object literal), irrespective (!) of ordering.
Put another way: no matter where (in the object literal) __proto__ appears — if it's there at all, it "wins" automatically.
Furthermore, hovering over protoFollowedBySpread reveals its inferred type to be:
{ readonly __proto__: null;}
...which is incorrect. The actual __proto__ is Array.prototype, which is why console.log('map' in protoFollowedBySpread) logs true at runtime.
Considering the broken type inference, I would wager to guess that the type checker is (as of yet) uneducated on the particular semantics at play in this somewhat rare (though well-defined) corner case of the language.
🔎 Search Terms
proto
spread
object literal
ts(2783)
specified more than once
will be overwritten
🕗 Version & Regression Information
This was the behavior I observed in every version I tried.
exportconstfoo={__proto__: null,}asconst;exportconstprotoFollowedBySpread={__proto__: Array.prototype,// This error is itself erroneous (in this one special case, specifically involving `__proto__` in object literals).
...foo,}asconst;exportconstspreadFollowedByProto={
...foo,__proto__: Array.prototype,// No error is reported when the "inline" `__proto__` comes AFTER `...foo`. No surprises here. ;}asconst;console.log('map'inprotoFollowedBySpread);// logs `true`(the inferred type is wrong)
🙁 Actual behavior
Please see the playground. In short:
Invalid type inference
False positive ts(2783)
Hint that (while a wonderful and friendly feature) happens to mislead in this particular case
🙂 Expected behavior
Simply put, a correct understanding of the language semantics in this case. Notable mentions here would be (two sides of the same coin):
No errors reported where nothing is wrong
Correctly inferring the type based on the (AFAIK) statically known properties involved
You are right, but this doesn’t seem like it needs to be a separate issue from #38385. We wouldn’t have any business understanding that __proto__ is special in a spread without understanding the other ways in which __proto__ is special. Maybe you’d like to comment on the related issue or PR instead to ensure this test case is covered?
Activity
andrewbranch commentedon Aug 26, 2021
You are right, but this doesn’t seem like it needs to be a separate issue from #38385. We wouldn’t have any business understanding that
__proto__is special in a spread without understanding the other ways in which__proto__is special. Maybe you’d like to comment on the related issue or PR instead to ensure this test case is covered?typescript-bot commentedon Aug 28, 2021
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.