better types 6.x by jdeniau · Pull Request #2204 · immutable-js/immutable-js · GitHub
Skip to content

better types 6.x - #2204

Merged
jdeniau merged 3 commits into
6.xfrom
better-types-6.x
Jun 1, 2026
Merged

jdeniau merged 3 commits into
6.xfrom
better-types-6.x

Conversation

@jdeniau

@jdeniau jdeniau commented Jun 1, 2026

Copy link
Copy Markdown
Member

Improves the TypeScript types of Collection.ts as part of the ongoing TS migration, removing hand-written as casts and @ts-expect-error suppressions in favour of properly inferred types.

find and related accessors

  • Add a NSV (not-set value) type parameter to find, and type findEntry's notSetValue as [K, V].
  • Drop the now-unnecessary casts in find, get, has, first and last (as V | undefined, as unknown as V, …) and remove a @ts-expect-error on notSetValue.

isSubset / isSuperset

  • Replace the scattered as unknown as { … } / as unknown as CollectionImpl casts with a small hasIncludesMethod type guard.
  • Rewrite isSuperset as Collection(iter).every((value) => this.includes(value)), which is behaviourally equivalent to the previous iter.isSubset(this) delegation but removes the this as unknown as Iterable<V> cast (isSubset is not overridden anywhere, so there was no polymorphism to preserve).
  • The type guard checks typeof iter === 'object' before using in, so passing a primitive iterable (e.g. a string) no longer throws.

Behaviour change: isSubset/isSuperset now normalize non-Immutable inputs through Collection() (based on isCollection) instead of duck-typing an arbitrary includes/isSubset method. A plain object that is not an Immutable collection but exposes its own includes/isSubset method will no longer have that method invoked — it is treated as a regular iterable. Immutable collections and arrays are unaffected.

reduce / reduceRight

  • Type the shared reduce helper generically, removing the @ts-expect-error and the as R cast at both call sites. The implementation signature now returns the honest V | R | undefined (the public overloads still return R).
  • Add an Array#reduce-style overload for the no-initial case where the accumulator is a value (R = V), so the result type is inferred from the collection's values instead of requiring an explicit type argument: list.reduce((a, b) => a + b) now infers number.

Tests

  • Add tstyche coverage for reduce/reduceRight (none existed before): result type with/without an initial value, the new value inference, and the reducer argument types across List, Map, Set and Collection.
  • Add unit tests: isSubset against arrays/collections and a primitive string (regression for the in throw), and reduce without an initial value (single value returns the seed, empty collection returns undefined).

CHANGELOG.md updated for the user-visible behaviour and type changes.

@jdeniau
jdeniau changed the base branch from main to 6.x June 1, 2026 14:32
@jdeniau
jdeniau marked this pull request as ready for review June 1, 2026 16:21
@jdeniau
jdeniau merged commit 72dd1b3 into 6.x Jun 1, 2026
5 checks passed
@jdeniau
jdeniau deleted the better-types-6.x branch June 1, 2026 16:22
jdeniau pushed a commit to jdeniau/immutable-js that referenced this pull request Aug 16, 2026
Each finding from .agents/migration-status.md was traced back to its
originating PR, then fixed or confirmed as an intentional change:

- R1 (isSubset string argument, from immutable-js#2204): keep the new
  character-iteration semantics, consistent with isSuperset and with
  Collection('abc'); documented as a v6 breaking change in the CHANGELOG
  and pinned by multi-char unit tests.
- R2 ('@@iterator' fallback removal, from immutable-js#2127): confirmed intended
  modernisation; explicit CHANGELOG entry, and the two immutable.d.ts
  docstrings no longer mention @@iterator. immutable.js.flow is left
  untouched since Flow's @@iterator syntax denotes Symbol.iterator.
- R3 (reverseFactory reverse-iteration keys, ?? 0 from immutable-js#2206, NaN keys
  already in v5): fixed by counting down from the number returned by
  ensureSize(collection) - the reversed sequence has the same size as
  its source. Regression tests cover both __iterate (reduceRight) and
  __iterator (keyed reverse) paths; CHANGELOG entry since the NaN
  behaviour shipped in v5.
- R4 (wholeSlice with begin === undefined, from immutable-js#2128): restored the
  faithful v5 form (begin !== undefined && begin <= -size) so slice()
  with no arguments goes through sliceFactory again, on empty
  collections too; identity regression test added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0122shfP2ngkkjuXZBWoeFGW
jdeniau pushed a commit to jdeniau/immutable-js that referenced this pull request Aug 16, 2026
Each finding from .agents/migration-status.md was traced back to its
originating PR, then fixed or confirmed as an intentional change:

- R1 (isSubset string argument, from immutable-js#2204): keep the new
  character-iteration semantics, consistent with isSuperset and with
  Collection('abc'); documented as a v6 breaking change in the CHANGELOG
  and pinned by multi-char unit tests.
- R2 ('@@iterator' fallback removal, from immutable-js#2127): confirmed intended
  modernisation; explicit CHANGELOG entry, and the two immutable.d.ts
  docstrings no longer mention @@iterator. immutable.js.flow is left
  untouched since Flow's @@iterator syntax denotes Symbol.iterator.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0122shfP2ngkkjuXZBWoeFGW
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