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
Overriding fields of a generic object using spread operator results in incorrect typesΒ #62831
This is vastly different than what's actually in the runtime. A field resulting in type number & string and therefore never, is especially dangerous, since now it can be assigned to any variable:
constdate: Date=foo.a// doesn't report any error
π Expected behavior
The inferred type of the function mapFoo should be:
Related issue: #50185 <- it was closed due to being a duplicate of #10727 , but I don't think they're duplicate. A type-level spread operator could help here, but the inferred type could be corrected using existing operators and types (Omit and &)
This issue doesn't happen for non-generic types, ie:
Note: not a TS team member, feel free to ignore me
This is indeed a duplicate of #50185 and #42690 and ultimately #10727. It's a duplicate because that's where they want to track all requests to accurately represent spread expressions in the face of possible property overwrites. If they decide to implement it using Omit, that would be a fix for #10727.
Thanks for the detailed explanation! Iβd like to add a bit more context about why I raised this.
First, I think this behavior is potentially a significant risk in real-world TypeScript codebases. In my case, it silently compromised type safety and spread through the code without being immediately obvious. Because the incorrect type inference appears valid, it can go unnoticed for a long time, which makes it especially concerning.
Regarding #10727 - it looks like that proposal has been on hold for quite a while. I understand that introducing new syntax or operators is a large thing and probably not the most urgent priority. From my perspective, this issue doesnβt need a brand-new operator to be resolved quickly.
Iβm not familiar with the internals of TypeScript, but it seems like fixing this through the Omit type might be a relatively easy fix. I realize that such a change could break existing code, but in this case I think thatβs appropriate: the current behavior hides mistakes rather than reporting them.
If it can be done with Omit then that implies you can do it yourself in userland, with the proviso that you need to replace spreads with some custom helper function that uses Omit. Indeed, such things have been done before, like in the SO question Merge object types?:
Any appetite to have this be part of the language itself as the return type of spread expressions will almost certainly be discussed in #10727. I'm pretty sure the reason it hasn't been implemented is summarized in #10727 (comment)
We never found the balance of correctness and usability for spread types that justified their complexity. At the time, React higher-order components also required negated types in order to be correctly typed. Finally, we decided that since we'd been using intersection as a workaround for so long, that it was good enough.
I understand the reasoning, but Iβd like to ask that this issue remain open, even if the long-term plan is to address it through a new operator in the future.
Keeping this issue open makes it clear that this is a recognized bug in TypeScript, and it greatly helps with communicating the problem to other developers. Consider a realistic scenario: someone on a team uses the spread operator together with a generic object type and overrides some fields. In a PR review, you point out that this is unsafe due to a known TypeScript bug and ask them to use an omit helper function to ensure type-safety. Itβs much easier to reference an open issue that clearly describes the problem and the workaround.
If this issue is closed in favor of #10727 , it becomes much harder to provide a relevant explanation, since #10727 isnβt specifically about this behavior. Having this issue remain open until the actual root cause is fixed would make the situation clearer for anyone encountering it.
Activity
jcalz commentedon Dec 3, 2025
Note: not a TS team member, feel free to ignore me
This is indeed a duplicate of #50185 and #42690 and ultimately #10727. It's a duplicate because that's where they want to track all requests to accurately represent spread expressions in the face of possible property overwrites. If they decide to implement it using
Omit, that would be a fix for #10727.wnadurski commentedon Dec 3, 2025
Thanks for the detailed explanation! Iβd like to add a bit more context about why I raised this.
First, I think this behavior is potentially a significant risk in real-world TypeScript codebases. In my case, it silently compromised type safety and spread through the code without being immediately obvious. Because the incorrect type inference appears valid, it can go unnoticed for a long time, which makes it especially concerning.
Regarding #10727 - it looks like that proposal has been on hold for quite a while. I understand that introducing new syntax or operators is a large thing and probably not the most urgent priority. From my perspective, this issue doesnβt need a brand-new operator to be resolved quickly.
Iβm not familiar with the internals of TypeScript, but it seems like fixing this through the Omit type might be a relatively easy fix. I realize that such a change could break existing code, but in this case I think thatβs appropriate: the current behavior hides mistakes rather than reporting them.
Just wanted to clarify my reasoning
jcalz commentedon Dec 3, 2025
If it can be done with
Omitthen that implies you can do it yourself in userland, with the proviso that you need to replace spreads with some custom helper function that usesOmit. Indeed, such things have been done before, like in the SO question Merge object types?:helper details
Playground link
Any appetite to have this be part of the language itself as the return type of spread expressions will almost certainly be discussed in #10727. I'm pretty sure the reason it hasn't been implemented is summarized in #10727 (comment)
wnadurski commentedon Dec 4, 2025
I understand the reasoning, but Iβd like to ask that this issue remain open, even if the long-term plan is to address it through a new operator in the future.
Keeping this issue open makes it clear that this is a recognized bug in TypeScript, and it greatly helps with communicating the problem to other developers. Consider a realistic scenario: someone on a team uses the spread operator together with a generic object type and overrides some fields. In a PR review, you point out that this is unsafe due to a known TypeScript bug and ask them to use an omit helper function to ensure type-safety. Itβs much easier to reference an open issue that clearly describes the problem and the workaround.
If this issue is closed in favor of #10727 , it becomes much harder to provide a relevant explanation, since #10727 isnβt specifically about this behavior. Having this issue remain open until the actual root cause is fixed would make the situation clearer for anyone encountering it.
jcalz commentedon Dec 4, 2025
#42690 is open π€·ββοΈ
wnadurski commentedon Dec 4, 2025
Oh, true then I agree we can close this issue