🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

Migrate mixin operations to real TypeScript class methods in Collection.ts - #2193

Merged
jdeniau merged 7 commits into
6.xfrom
extract-mixin-operations
Jun 1, 2026
Merged

Migrate mixin operations to real TypeScript class methods in Collection.ts#2193
jdeniau merged 7 commits into
6.xfrom
extract-mixin-operations

Conversation

@jdeniau

@jdeniau jdeniau commented May 27, 2026

Copy link
Copy Markdown
Member

Summary

Follows #2192 and builds on the Operations.js split (#2194). Migrates a large
batch of mixin methods out of CollectionImpl.js into real TypeScript class
methods
on the Collection.ts classes — a concrete step toward deleting
src/utils/mixin.ts.

What changed

  • Real class methods (no longer mixin entries) on CollectionImpl /
    KeyedCollectionImpl / IndexedCollectionImpl: map, toSeq, filter,
    filterNot, partition, reverse, slice, sort, sortBy, flatMap,
    flatten, max/maxBy/min/minBy, skip/skipLast/skipWhile/skipUntil,
    take/takeLast/takeWhile/takeUntil, butLast, rest, count,
    findLast/findLastEntry/findLastKey/findLastIndex, lastKeyOf/lastIndexOf,
    last, keySeq/valueSeq, flip, findIndex/indexOf, interpose/interleave,
    zip/zipAll/zipWith. Implementations delegate to the operations/factories

    • operations/helpers functions (import-safe — no eval-time extends, no Map
      import, so no load-order cycle).
  • Removed the temporary interface declaration merging for map/toSeq: the
    real method bodies now carry the types directly.

  • IS_*_SYMBOL brands are real runtime props assigned on the prototypes in
    Collection.ts (IS_COLLECTION_SYMBOL, IS_KEYED_SYMBOL, IS_INDEXED_SYMBOL,
    IS_ORDERED_SYMBOL). They make the otherwise structurally-identical empty
    subclasses distinct, which fixes this collapsing to never in toSeq's
    isIndexed/isKeyed narrowing, and they are what isKeyed/isIndexed/… test
    at runtime. They must live on the prototype (not as class fields) because
    makeSequence uses Object.create(prototype) and bypasses the constructor.

  • Every overload is preserved (e.g. filter/partition type-guard overloads,
    flatMap indexed-vs-keyed, flatten number-vs-boolean, the zip family arity
    overloads), with a single loose implementation signature — matching the
    hand-written type-definitions/immutable.d.ts.

  • Migration guide updated (.agents/commands/migrate-to-ts.md): added a step
    documenting overload preservation.

CollectionImpl.js shrinks accordingly; the 3 mixin(...SeqImpl, ...) calls and
the conversion/aggregation methods that still depend on operations/sequences.js
(eval-time extends) and operations/aggregations.js (imports Map) are
intentionally left for a later PR.

Tests

  • Unit — behavioral tests live in the instance files where the shared methods
    are exercised through concrete types: __tests__/List.ts (indexed helpers +
    edge cases), __tests__/Map.ts (keyed variants), __tests__/toSeq.ts.
  • Type (TSTyche)type-definitions/ts-tests/collection.ts covers return
    types and overloads across List/Map/Set/Seq, including type-guard narrowing,
    the zip tuple arities, flip, and error cases (indexed-only methods on keyed
    collections).
  • src/Collection.ts line coverage ~97% (remainder = abstract __iterate/
    __iterator stubs, unreachable from the public API).

Test plan

  • npm run type-check — 0 errors
  • npm run test:unit — green
  • npm run test:types — green
  • npm run lint / npm run format — clean

@jdeniau
jdeniau changed the base branch from 6.x to extract-mixin-simple-functions May 27, 2026 20:34
@jdeniau
jdeniau force-pushed the extract-mixin-simple-functions branch from f998274 to caa2c38 Compare May 28, 2026 21:30
Base automatically changed from extract-mixin-simple-functions to 6.x May 28, 2026 21:52
@jdeniau
jdeniau force-pushed the extract-mixin-operations branch 5 times, most recently from eb98970 to 9610e04 Compare May 29, 2026 09:48
@jdeniau jdeniau changed the title Type mixin-provided toSeq / map via interface declaration merging Migrate mixin operations to real TypeScript class methods in Collection.ts May 31, 2026
@jdeniau
jdeniau force-pushed the extract-mixin-operations branch from 0d23ac2 to c1aa7c7 Compare May 31, 2026 19:15
@jdeniau
jdeniau force-pushed the extract-mixin-operations branch 3 times, most recently from 485786d to c313118 Compare June 1, 2026 17:20
jdeniau added a commit that referenced this pull request Jun 1, 2026
jdeniau and others added 7 commits June 1, 2026 20:34
The base `toIndexedSeq`/`toKeyedSeq`/`toSetSeq` were declared as returning
the loose `CollectionImpl<K, V>`, which forced `as unknown as` casts in
`keySeq`/`valueSeq`. Declare them with their concrete return types and route
`toSeq` through the subclasses, where the key type is fixed by the class, so
no assertion is needed.

- Narrow the three `to*Seq` declarations to IndexedCollectionImpl<V> /
  KeyedCollectionImpl<K, V> / SetCollectionImpl<V>.
- Distribute `toSeq` into IndexedCollectionImpl / SetCollectionImpl overrides
  (concrete K) and keep the keyed case on the base — no casts.
- Annotate the identity `to*Seq` overrides in Seq.js via JSDoc @returns so the
  Seq classes satisfy the tightened types (type-only, runtime unchanged).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jdeniau
jdeniau force-pushed the extract-mixin-operations branch 2 times, most recently from 4c79bfe to c901901 Compare June 1, 2026 20:40
@jdeniau
jdeniau merged commit 61e55f8 into 6.x Jun 1, 2026
5 checks passed
@jdeniau
jdeniau deleted the extract-mixin-operations branch June 1, 2026 20:44
pull Bot pushed a commit to itsrbpandit/immutable-js that referenced this pull request Jun 1, 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