Skip to content

fix: type curried recipes whose draft is annotated with a type parameter - #204

Merged
unadlib merged 3 commits into
mainfrom
fix/curried-recipes-of-type-parameters
Oct 11, 2026
Merged

unadlib merged 3 commits into
mainfrom
fix/curried-recipes-of-type-parameters

Conversation

@unadlib

@unadlib unadlib commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Part of #168.

Summary

# Issue main and npm 1.3.0 This PR
1 A curried recipe in a generic function whose draft is annotated with the type parameter, as in create(async (draft: T) => { … }) in function update<T extends object>() typed as a manual draft, [draft, finalize], so calling the producer does not compile ("This expression is not callable", TS2349); the same for synchronous recipes, recipes that return a new state and recipes with arguments, while the call returns a producer at run time (base: T) => T, or (base: T) => Promise<T> for an async recipe, with the arguments of the recipe

The overload that infers the state type of a curried producer takes a recipe typed (draft: Draft<T>, ...args: P) => R, and TypeScript cannot match a draft typed as a type parameter against Draft<T>, so the overload of a manual draft accepts the recipe as the base state. Direct calls already have an overload for a draft typed as the state itself, (base: T, mutate: (draft: T) => R); this PR adds its curried counterpart. Annotating the draft as Draft<T> worked before and still does.

Changes, one commit per item

  1. fix: type a curried recipe whose draft is annotated with a type parameter: the curried overload for a draft typed as the state, after the one that takes Draft<T>. A type test covers synchronous and async recipes, a recipe with an argument and one that returns a new state, and checks their results at run time.
  2. docs: describe curried recipes whose draft is annotated with a type parameter: the migration guide in the README and on the website, and the advice for generic code under async recipes in the README and on the create() page, which now shows the curried form as well.
  3. docs: regenerate the API reference: the new signature of create() and makeCreator(); the links point to the commit before it.

Behavior changes to review

  • These calls now type-check and give producers, where they did not compile. No call that compiled before changes its type among the shapes checked below.

Verification

  • The type test fails on main with eight errors: four type assertions and four calls of a value without a call signature.
  • 178 call shapes, among them the 76 that fix: harden apply() for Set positions and mutable root replacement, and fix development checks and recipe types #201 and fix: bound the search for repeated moved array elements and type maybe-async recipes of primitive states #202 were checked with, on TypeScript 5.0.4, 5.1.6, 5.8.3 and 5.9.3, with and without strict mode, 1,424 types in all: only the ten types of the new shapes change.
  • Type-checking 150 calls per shape with TypeScript 5.8.3: curried calls with a concrete annotated draft, curried calls with an explicit state type and direct calls without type arguments take the same number of instantiations as on main (7,482, 12,219 and 11,840); generic factories whose draft is typed T take 17,397 instead of 17,576 and now give producers.
  • Size: types only. Every artifact and consumer bundle keeps its size (all deltas of size:compare are 0); the declaration of makeCreator grows from 4,554 B to 4,829 B.
  • The local CI sequence passes: lint, format, build, the benchmark checks, test:benchmarks, size, test:package with its TypeScript 5.0 consumer, test:build-watch, type-check and 5,041 tests.

Not covered

@github-actions

Copy link
Copy Markdown

Coverage after merging fix/curried-recipes-of-type-parameters into main will be

100.00%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   apply.ts100%100%100%100%
   array.ts100%100%100%100%
   constant.ts100%100%100%100%
   create.ts100%100%100%100%
   current.ts100%100%100%100%
   draft.ts100%100%100%100%
   draftify.ts100%100%100%100%
   error.ts100%100%100%100%
   index.ts100%100%100%100%
   interface.ts100%100%100%100%
   internal.ts100%100%100%100%
   makeCreator.ts100%100%100%100%
   map.ts100%100%100%100%
   original.ts100%100%100%100%
   patch.ts100%100%100%100%
   rawReturn.ts100%100%100%100%
   set.ts100%100%100%100%
   unsafe.ts100%100%100%100%
src/utils
   cast.ts100%100%100%100%
   copy.ts100%100%100%100%
   deepFreeze.ts100%100%100%100%
   draft.ts100%100%100%100%
   finalize.ts100%100%100%100%
   forEach.ts100%100%100%100%
   index.ts100%100%100%100%
   mark.ts100%100%100%100%
   marker.ts100%100%100%100%
   proto.ts100%100%100%100%

@unadlib
unadlib merged commit 40f3a42 into main Oct 11, 2026
10 checks passed
@unadlib
unadlib deleted the fix/curried-recipes-of-type-parameters branch October 11, 2026 14:08
@unadlib unadlib mentioned this pull request Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant