Skip to content

fix: narrow channel.state.typing to typing.start events - #1960

Merged
oliverlaz merged 1 commit into
release-v10from
fix/narrow-typing-state-type
Oct 29, 2026
Merged

oliverlaz merged 1 commit into
release-v10from
fix/narrow-typing-state-type

Conversation

@oliverlaz

Copy link
Copy Markdown
Member

Ticket: https://linear.app/stream/issue/REACT-1466

CLA

  • I have signed the Stream CLA (required).
  • Code changes are tested

Description of the changes, What, Why and How?

In v10 Event is a discriminated union, but channel.state.typing was still typed Record<string, Event>. Any custom typing indicator that reads event.user or event.parent_id stopped compiling and needed a hand-written (e): e is EventPayload<'typing.start'> => e.type === 'typing.start' guard. Found while migrating the stream-chat-react demo apps to v15 rc (stream-chat 10.0.0-rc.26).

Only typing.start events are ever stored in that slice. The one writer is the typing.start case in Channel._handleChannelEvent (guarded on event.user?.id), typing.stop only removes an entry, and clean() only reads received_at. So the type is narrowed to match what is stored:

  • TypingUsersState.typing (and so ChannelStateData['typing']), the channel.state.typing setter and setTypingEvent now use Record<string, EventPayload<'typing.start'>> / EventPayload<'typing.start'>. No new exported alias.
  • New compile-time test test/types/typing-state.ts (runs in yarn types and types:dist): Object.values(channel.state.typing)[0].user?.id and .parent_id compile with no guard, the slice type is pinned, and passing a typing.stop to setTypingEvent is rejected. Against the old types it fails with 6 errors.

ai-docs/v10-breaking-changes.md:

  • §7 (ChannelState is a StateStore<ChannelStateData>): the parenthetical said stream-chat-react's TypingIndicator "reads the composer copy", which contradicted the same sentence (channel.state is the only owner) and the React v15 guide. It now says the indicator reads channel.state, and documents the narrowed type.
  • §18: dropped the "TextComposerState.typing added as required" entry and the typing / setTyping / setTypingEvent / removeTypingEvent members from the TextComposer row of the added-members table. That composer copy was removed in fix: v10 in depth review hotfixes #1920, so both described an API that no longer exists and contradicted §7.

Compatibility: this is narrower than before, so code that assigned non-typing.start events into channel.state.typing or setTypingEvent no longer compiles. Nothing in the SDK does that, and readers only gain.

Test results

  • yarn types: pass (includes types:scripts and types:tests)
  • yarn lint: clean, zero warnings
  • yarn test: 135 files, 4820 tests passed

Changelog

  • channel.state.typing and ChannelState.setTypingEvent are typed as typing.start events, so event.user reads without a type guard.

Only typing.start events are stored in the typing slice (typing.stop
removes the entry), so type it as Record<string, EventPayload<'typing.start'>>
instead of the Event union. Typing indicators can read event.user and
event.parent_id without a hand-written guard.

Also fixes v10-breaking-changes.md: the ChannelState entry now says
stream-chat-react's TypingIndicator reads channel.state, and the stale
TextComposerState.typing entry (removed in #1920) is dropped.
@oliverlaz
oliverlaz merged commit acb2345 into release-v10 Oct 29, 2026
4 checks passed
@oliverlaz
oliverlaz deleted the fix/narrow-typing-state-type branch October 29, 2026 10:10
github-actions Bot pushed a commit that referenced this pull request Oct 30, 2026
## [10.0.0-rc.27](v10.0.0-rc.26...v10.0.0-rc.27) (2026-10-30)

### Bug Fixes

* consolidate master and v10 ([#1957](#1957)) ([802a956](802a956))
* handle tokenProvider rejection during reconnect token refresh ([#1963](#1963)) ([e22d218](e22d218))
* narrow channel.state.typing to typing.start events ([#1960](#1960)) ([acb2345](acb2345)), closes [#1920](#1920)
* odd edge cases for channel list recovery ([#1966](#1966)) ([dbc2468](dbc2468))
* pass full request options to hydration query ([#1959](#1959)) ([489774b](489774b))

### Features

* regenerate from latest api spec; docs sync ([#1969](#1969)) ([ae1e86a](ae1e86a))
@stream-ci-bot

Copy link
Copy Markdown

🎉 This PR is included in version 10.0.0-rc.27 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants