Skip to content

Conversation

@deepakbhagatiitr
Copy link

@deepakbhagatiitr deepakbhagatiitr commented Nov 14, 2025

I fixed a type-safety issue in RoomContext by replacing the any type used for the room property with a proper union type called TRoomContextRoom. This brings back full TypeScript checking and also removes a blocker for migrating RoomView to hooks.

Issue(s)

Fixes bug: #6799


Problem

The room field in IRoomContext was typed as any, which caused problems like:

  • TypeScript couldn’t validate anything
  • It made the RoomView migration to hooks harder
  • There was already a FIXME comment showing this was known technical debt

Solution

I created a new union type named TRoomContextRoom based on how the room value is actually used in IRoomViewState.room.


Details

File updated: app/views/RoomView/context.ts

What I changed:

  • Added the new union type TRoomContextRoom
  • Updated IRoomContext so room uses this new type instead of any
  • Removed the old FIXME comment
  • Added the required imports for ILastMessage and TSubscriptionModel

The new type works fully with the existing code:

  • RoomView already uses data shaped exactly this way
  • ShareView uses TSubscriptionModel, which is part of the union
  • No other files needed updates

Summary by CodeRabbit

  • Refactor
    • Strengthened typing and expanded the room/message context API to improve message editing, quoting, and autocomplete handling.
  • Chores
    • Updated internal declarations and tests to align with the strengthened typings.

Note: No visible UI changes; existing functionality remains unchanged, with behind-the-scenes improvements to message composition and context behavior.

- Replace 'any' type with proper TRoomContextRoom union type

- TRoomContextRoom matches IRoomViewState.room definition

- Supports both TSubscriptionModel and partial room objects (for threads)

- Removes FIXME comment and unblocks RoomView migration to hooks
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 14, 2025

Walkthrough

Introduces stricter typing for rooms: adds TRoomContextRoom, narrows room.t to RoomType, expands IRoomContext with new message/edit/autocomplete APIs, and updates related tests, stack types, definitions, and RoomView initialization to use the new types.

Changes

Cohort / File(s) Summary
Room Context Type Refinement
app/views/RoomView/context.ts
Added exported TRoomContextRoom (union of TSubscriptionModel or partial room shape); changed IRoomContext.room from any to TRoomContextRoom; added imports (ILastMessage, RoomType, TSubscriptionModel); expanded IRoomContext with selectedMessages, editCancel, editRequest, onRemoveQuoteMessage, onSendMessage, setQuotesAndText, getText, and updateAutocompleteVisible.
Room type discriminator tightening
app/views/RoomView/definitions.ts, app/stacks/types.ts
Replaced string literal type for room t with imported RoomType in state/type declarations.
RoomView initialization typing
app/views/RoomView/index.tsx
Cast default/route room object to IRoomViewState['room']; ensure t defaults using RoomType cast ('d' as RoomType) instead of plain string.
Test typing adjustment
app/containers/MessageComposer/MessageComposer.test.tsx
Imported RoomType and cast test fixture room.t to RoomType ('d' as RoomType) for stricter typing; no runtime logic change.
Manifest / package metadata
manifest_file, package.json
Manifest/package files updated (details not provided in summary).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify TRoomContextRoom aligns with existing usages and no incompatible assumptions remain.
  • Confirm RoomType values and casts ('d' as RoomType) match allowed enum/union members.
  • Check newly added IRoomContext method names/signatures against call sites.
  • Ensure no new implicit-any or type assertion issues in downstream files (tests, stacks, index).

Suggested reviewers

  • diegolmello

Poem

A rabbit tweaks the types with care,
Replacing any with structure rare.
Rooms now speak in clearer tone,
Callbacks hop and types have grown. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding proper typing (TRoomContextRoom type) to replace the 'any' type for the room property in RoomContext, which is the primary focus across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3532447 and d95cb97.

📒 Files selected for processing (1)
  • app/views/RoomView/context.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/views/RoomView/context.ts (2)
app/definitions/ISubscription.ts (1)
  • TSubscriptionModel (121-124)
app/definitions/IMessage.ts (1)
  • ILastMessage (54-75)
🔇 Additional comments (2)
app/views/RoomView/context.ts (2)

3-3: LGTM: Necessary imports added.

The type-only imports for ILastMessage and TSubscriptionModel are correctly added to support the new type definition.


30-30: Type change verified as safe and correct across all consumers.

The room property is used in two places within ComposerInput.tsx:

  • Line 62: room.t === 'd' (guarded by room && check)
  • Line 311: room?.t === 'l' (using optional chaining)

Both union members of TRoomContextRoom include the required t: string property, so all type access patterns are valid. The new type properly enforces safe access patterns that were previously masked by the any type.

- Update TRoomContextRoom to use RoomType ('c' | 'd' | 'p' | 'l') instead of generic string
- Update IRoomViewState.room to use RoomType for consistency
- Update route params type in ChatsStackParamList to use RoomType
- Fix type assertions in RoomView constructor and MessageComposer test
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/containers/MessageComposer/MessageComposer.test.tsx (1)

11-16: Fix duplicate ../../definitions imports to satisfy ESLint

ESLint's import/no-duplicates error comes from importing ../../definitions twice (lines 12 and 15: once for IMessage, once for RoomType). Consolidate into a single import:

-import { type IMessage } from '../../definitions';
+import { type IMessage, type RoomType } from '../../definitions';
-import { type RoomType } from '../../definitions';

The t: 'd' as RoomType assignment at line 81 is valid and will work correctly with the consolidated import, as 'd' is a valid member of the RoomType union ('c' | 'd' | 'p' | 'l').

🧹 Nitpick comments (2)
app/stacks/types.ts (1)

3-19: Aligning RoomView route room.t with RoomType is consistent

Importing RoomType and constraining RoomView’s optional room param so that its inline variant uses t: RoomType keeps the navigation type consistent with IRoomViewState.room and the RoomContext API. The shape { rid; t; name?; fname?; prid? } is a reasonable minimal subset for routing.

If you find more places duplicating this inline room shape, consider extracting a shared type alias (e.g., a lightweight “navigation-room” type) to avoid drift, provided it doesn’t introduce circular deps.

Also applies to: 31-46

app/views/RoomView/index.tsx (1)

57-70: RoomType integration is solid; double‑check the this.t as RoomType fallback for thread routes

Importing RoomType, casting the constructed room to IRoomViewState['room'], and passing room.t as RoomType into RoomServices.getMessages and LoadMore all move RoomView toward a single, well‑typed room shape that matches the new RoomContext API. For “normal” rooms where room is a TSubscriptionModel, room.t is a genuine RoomType, so those casts are effectively just helping TypeScript.

The only place that deserves a second look is the constructor fallback:

const room = (props.route.params?.room ?? {
  rid: this.rid as string,
  t: (this.t as RoomType) || ('d' as RoomType),
  name,
  fname,
  prid
}) as IRoomViewState['room'];

When navigating to threads, props.route.params.t is set to SubscriptionType.THREAD, so this.t can be a value that does not belong to the RoomType = 'c' | 'd' | 'p' | 'l' union. In those cases:

  • (this.t as RoomType) is a compile‑time lie: at runtime it’s still 'thread' (or whatever the SubscriptionType value is).
  • Because 'thread' is truthy, the || 'd' fallback doesn’t kick in, so the inline room object will have t: 'thread' while the type claims RoomType.

That’s consistent with pre‑PR runtime behavior (you were already passing this.t through), but now TypeScript thinks room.t is strictly a RoomType everywhere, which may mask future misuse.

If SubscriptionType is guaranteed to be a subset of RoomType in all cases where props.route.params.room is omitted, then this is fine. Otherwise, consider one of:

  • Narrowing at runtime before assigning:

    const allowedTypes: RoomType[] = ['c', 'd', 'p', 'l'];
    const fallbackT: RoomType =
      this.t && allowedTypes.includes(this.t as RoomType)
        ? (this.t as RoomType)
        : 'd';
    
    const room = (props.route.params?.room ?? {
      rid: this.rid as string,
      t: fallbackT,
      name,
      fname,
      prid
    }) as IRoomViewState['room'];
  • Or, if thread routes intentionally use a non‑RoomType discriminator in room.t, widening the inline variant in IRoomViewState['room'] (and the corresponding TRoomContextRoom) to reflect that.

Either approach keeps the improved type‑safety you’re aiming for while avoiding a silent cast that may hide real mismatches.

Also applies to: 135-155, 576-592, 1316-1323

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d95cb97 and 1be3ab4.

📒 Files selected for processing (5)
  • app/containers/MessageComposer/MessageComposer.test.tsx (2 hunks)
  • app/stacks/types.ts (2 hunks)
  • app/views/RoomView/context.ts (1 hunks)
  • app/views/RoomView/definitions.ts (2 hunks)
  • app/views/RoomView/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/views/RoomView/context.ts
🧰 Additional context used
🧬 Code graph analysis (4)
app/stacks/types.ts (2)
app/definitions/ISubscription.ts (1)
  • TSubscriptionModel (121-124)
app/definitions/IRoom.ts (1)
  • RoomType (147-147)
app/views/RoomView/definitions.ts (1)
app/definitions/IRoom.ts (1)
  • RoomType (147-147)
app/containers/MessageComposer/MessageComposer.test.tsx (1)
app/definitions/IRoom.ts (1)
  • RoomType (147-147)
app/views/RoomView/index.tsx (2)
app/definitions/IRoom.ts (1)
  • RoomType (147-147)
app/views/RoomView/definitions.ts (1)
  • IRoomViewState (41-73)
🪛 ESLint
app/containers/MessageComposer/MessageComposer.test.tsx

[error] 15-15: '/home/jailuser/git/app/definitions/index.ts' imported multiple times.

(import/no-duplicates)

🔇 Additional comments (1)
app/views/RoomView/definitions.ts (1)

4-12: Stricter room.t typing with RoomType looks good

Using RoomType for IRoomViewState.room’s inline variant (and importing it here) tightens the state shape to the canonical 'c' | 'd' | 'p' | 'l' set and fits the Room-related typings used elsewhere (e.g., IRoom.ts). No issues from this change on its own.

Also applies to: 41-57

- Merge duplicate ../../definitions imports into single import statement
- Fixes ESLint import/no-duplicates error
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
app/containers/MessageComposer/MessageComposer.test.tsx (1)

81-81: Type assertion is correct; consider consistency improvement.

The type assertion correctly ensures 'd' is recognized as RoomType. The value 'd' is a valid member of the RoomType union.

However, for consistency, Line 509 also assigns a room type ('l') without using the same type assertion pattern:

room: { ...initialContext.room, t: 'l' }

Consider applying the same pattern for consistency:

-room: { ...initialContext.room, t: 'l' }
+room: { ...initialContext.room, t: 'l' as RoomType }

This makes the type constraint explicit across all test cases.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1be3ab4 and 5044577.

📒 Files selected for processing (1)
  • app/containers/MessageComposer/MessageComposer.test.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/containers/MessageComposer/MessageComposer.test.tsx (1)
app/definitions/IRoom.ts (1)
  • RoomType (147-147)
🔇 Additional comments (1)
app/containers/MessageComposer/MessageComposer.test.tsx (1)

12-12: LGTM! Import addition is correct.

The RoomType import is properly added and necessary for the type assertion used in the test context.

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