Skip to content

fix: recursive T for WritableDraft - #1197

Merged
mweststrate merged 2 commits into
immerjs:mainfrom
unional:draft
Dec 29, 2025
Merged

fix: recursive T for WritableDraft#1197
mweststrate merged 2 commits into
immerjs:mainfrom
unional:draft

Conversation

@unional

Copy link
Copy Markdown
Contributor

This contains a proper fix for #990

Added tests for the type check.

Included #1196 as I don't want to see the type errors in the tests.

@coveralls

coveralls commented Dec 22, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 20424663455

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.01%) to 42.865%

TotalsCoverage Status
Change from base Build 20394930238:-0.01%
Covered Lines:1678
Relevant Lines:4771

💛 - Coveralls

@mweststrate

Copy link
Copy Markdown
Collaborator

Looks great, thanks!

@mweststrate
mweststrate merged commit 78ea694 into immerjs:mainDec 29, 2025
1 check passed
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 11.1.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

@wereHamster

Copy link
Copy Markdown
Contributor

Looks like this change is causing the following code to fail:

functionTest<A>(){produce((draft)=>{draft.prop=undefined;// <- type error here},{prop: undefinedasundefined|A},);}

Type error on indicated line:

Type undefined is not assignable to type A | undefined extends infer V ? V extends object ? Draft : V : never

@unional

unional commented Jan 19, 2026

Copy link
Copy Markdown
ContributorAuthor

Looks like this change is causing the following code to fail:

I can reproduce it. It seems like the type cannot be resolved partially like this.

Is there a particular use case for this? Is there a reason to declare the type like this rather than as a whole like:

functionTest<Aextends{prop: undefined}>(){produce((draft)=>{draft.prop=undefined;},{prop: undefined}asA,);}

@wereHamster

Copy link
Copy Markdown
Contributor

My full code is more like this:

functionMultiLineChart<AextendsTDatum<{}>>(props: Props<A>){const[state,mutate]=useImmer({hovered: undefinedasundefined|A,});constresetHover=React.useCallback(()=>{mutate((draft)=>{draft.hovered=undefined;// <- type error here});},[mutate]);}

Interestingly, the following (which is quite close to your code) also errors:

functionTest<A>(){typeS={prop: undefined|A}produce((draft)=>{draft.prop=undefined;// <- type error here},{prop: undefined}asS,);}

@unional

Copy link
Copy Markdown
ContributorAuthor

The issue is S is being distributed to Draft<S> and S.
Since TypeScript cannot determine the type of A during static analysis, it fails.

I have a fix to defer the analysis. Let me create a PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@unional@coveralls@mweststrate@wereHamster