Skip to content

fix: typescript migration helpers 6781 - #6796

Closed
DSingh0304 wants to merge 0 commit into
RocketChat:developfrom
DSingh0304:fix/typescript-migration-helpers-6781
Closed

fix: typescript migration helpers 6781#6796
DSingh0304 wants to merge 0 commit into
RocketChat:developfrom
DSingh0304:fix/typescript-migration-helpers-6781

Conversation

@DSingh0304

@DSingh0304 DSingh0304 commented Nov 14, 2025

Copy link
Copy Markdown

Proposed changes

This PR completes the TypeScript migration for app/lib/methods/helpers/helpers.ts by removing the @ts-nocheck directive and adding proper type annotations to all helper functions.

Key changes:

  • Removed @ts-nocheck directive from helpers.ts
  • Added comprehensive TypeScript types and JSDoc comments to all 8 exported helper functions
  • Created TRoomLike type alias to handle both IRoom and ISubscription objects flexibly
  • Updated function signatures to handle undefined inputs gracefully, ensuring type safety
  • Added null checks in calling code (RoomActionsView, RoomInfoView, RoomView) to prevent passing undefined values to getUserInfo

All functions now have proper type annotations:

  • isGroupChat, getRoomAvatar, getUidDirectMessage, getRoomTitle, getSenderName, canAutoTranslate, isRead, hasRole, hasPermission

Issue(s)

Fixes #6781

How to test or reproduce

  1. Run yarn tsc --noEmit to verify TypeScript compilation passes without errors
  2. Run yarn lint app/lib/methods/helpers/helpers.ts to verify ESLint passes
  3. Test the following screens to ensure functionality remains unchanged:
    • Room Actions View
    • Room Info View
    • Room View (main chat screen)
  4. Verify direct message user info loading works correctly
  5. Verify room titles and avatars display properly

Screenshots

N/A - Type-only changes, no visual modifications

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

This is a type-safety improvement with no runtime behavior changes. The TypeScript migration ensures better code maintainability and catches potential type errors at compile time. All existing functionality is preserved while improving type safety across the codebase.

Verification completed:

  • ✅ TypeScript compilation: 0 errors in application code
  • ✅ Metro bundler: Successfully builds for Android
  • ✅ ESLint: Passes with no errors/warnings
  • ✅ Git status: Clean working directory with only 4 files modified (85 insertions, 40 deletions)

Summary by CodeRabbit

  • Bug Fixes

    • Avoided unnecessary user-info fetches when identifiers are missing; prevents runtime errors.
    • Ensured room titles, names and related props always resolve to defined strings (safe fallbacks).
    • Coerced permission checks and boolean results to avoid undefined values.
  • Refactor

    • Improved null-safety and type robustness across helpers, hooks and views.
    • Made avatar fields optional so missing avatars render safely.
    • Hardened read/unread, sender-name and permission handling to reduce edge-case failures.
  • Documentation

    • Added JSDoc-style comments for clearer intent and maintenance.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Nov 14, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds TypeScript typings and null-safety to helpers in app/lib/methods/helpers/helpers.ts; makes avatar props optional; and guards calls to getUserInfo and room-title usages across multiple view and container components to ensure safe fallbacks.

Changes

Cohort / File(s) Summary
TypeScript migration & null-safety for helpers
app/lib/methods/helpers/helpers.ts
Remove @ts-nocheck; introduce internal TRoomLike; add/strengthen types and JSDoc for exported helpers (e.g., `isGroupChat(room: Partial
Guard getUserInfo with roomUserId checks (views)
app/views/RoomActionsView/index.tsx, app/views/RoomInfoView/index.tsx, app/views/RoomView/index.tsx
Only call getUserInfo when roomUserId is truthy; adjust calls to getUidDirectMessage to pass `r
Make avatar fields optional across UI components
app/containers/CallHeader.tsx, app/containers/InAppNotification/IncomingCallNotification/index.tsx, app/containers/InAppNotification/NotifierComponent.tsx, app/containers/RoomItem/interfaces.ts
Change avatar from required string to optional (`string
UI guards and string fallbacks
app/containers/RoomItem/index.tsx, app/views/AddExistingChannelView/index.tsx, app/views/CreateDiscussionView/SelectChannel.tsx, app/views/CreateDiscussionView/SelectUsers.tsx, app/views/ForwardMessageView/SelectPersonOrChannel.tsx, app/views/RoomInfoEditView/index.tsx, app/views/ShareView/Header.tsx
Use `getRoomTitle(...)
Permissions boolean-hardening
app/views/RoomActionsView/index.tsx, app/containers/MessageActions/index.tsx, app/views/RoomView/RightButtons.tsx, app/views/ShareView/index.tsx
Ensure permission results coerce to boolean (e.g., `permissions[0]
Typed hook state
app/lib/hooks/useUserData.ts
Add explicit useState typing for user data: { username: string; avatar?: string; uid: string; type: string; direct: boolean }.
RoomItem rendering fallback
app/containers/RoomItem/index.tsx
Pass `name

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas needing extra attention:
    • hasPermission async flow: room role loading, role merging, and error fallback behavior.
    • Callers previously expecting null vs now receiving undefined from getUidDirectMessage.
    • UI code that assumed avatars are always present — verify fallbacks and rendering across components.
    • Correctness of TRoomLike fields for federated and direct-message shapes.

Possibly related PRs

  • feat(ABAC): Add icons #6758 — modifies app/containers/RoomItem/interfaces.ts (avatar/props changes) and adds related interface fields; likely overlaps with avatar optionality changes.

Suggested reviewers

  • OtavioStasiak
  • diegolmello

Poem

🐰 I hopped through code with careful paws,
Typed the helpers and fixed the laws.
Avatars optional, titles never nil,
Guards in place to keep calls still.
A small rabbit's tweak — tidy and chill. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly describes the main change: removing @ts-nocheck and adding TypeScript types to helpers. It directly matches the primary objective in the linked issue #6781.
Linked Issues check ✅ Passed The PR successfully addresses all objectives from issue #6781: removed @ts-nocheck, added complete TypeScript annotations and JSDoc to all 8 exported functions (isGroupChat, getRoomAvatar, getUidDirectMessage, getRoomTitle, getSenderName, canAutoTranslate, isRead, hasRole, hasPermission), introduced TRoomLike type, and updated downstream callers.
Out of Scope Changes check ✅ Passed All changes are directly aligned with #6781 objectives: TypeScript migration of helpers.ts and necessary downstream updates in RoomActionsView, RoomInfoView, RoomView, and type definitions. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ 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.

@DSingh0304 DSingh0304 changed the title Fix/typescript migration helpers 6781 fix: typescript migration helpers 6781 Nov 14, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (2)
app/lib/methods/helpers/helpers.ts (2)

31-88: getUidDirectMessage and getRoomTitle improvements; consider guarding missing login user

The new getUidDirectMessage behavior (explicit string | undefined, itsMe support, group-chat early return) and getRoomTitle’s federated/DM-aware logic nicely tighten nullability and make call sites safer.

One potential hardening: destructuring from reduxStore.getState().login.user will throw if login.user is ever unset (e.g., early in app start). You could defensively guard that to fail closed instead of crashing:

-export function getUidDirectMessage(room: (Partial<TRoomLike> & { itsMe?: boolean }) | null | undefined): string | undefined {
-	const { id: userId } = reduxStore.getState().login.user;
+export function getUidDirectMessage(room: (Partial<TRoomLike> & { itsMe?: boolean }) | null | undefined): string | undefined {
+	const loginUser = reduxStore.getState().login.user;
+	const userId = loginUser?.id;
+
+	if (!loginUser || !userId) {
+		return undefined;
+	}

This keeps the current semantics for normal flows while making the helper more robust to state shape changes.


90-156: Permission/flags helpers are safer; minor comment/observability nits

The revised canAutoTranslate, isRead, hasRole, and hasPermission implementations all look correct and more null-safe:

  • canAutoTranslate now cleanly bails out on settings/permission misconfiguration and logs unexpected errors.
  • isRead’s use of unread ?? 0 and alert === true avoids undefined pitfalls.
  • hasPermission correctly merges room and user roles, handles undefined permission entries, and returns an all‑false array on lookup or state errors.

Two minor polish ideas:

  • In isRead, the comment “item is not archived and not opened” doesn’t match item.open === true; clarifying that comment to “item is not archived and is open” would avoid confusion.
  • In the hasPermission catch block where the room isn’t found, using the shared log helper (or including rid in the message) instead of a bare console.log would make it easier to trace permission issues in production logs.

Both are optional and don’t affect correctness.

📜 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 28559ba.

📒 Files selected for processing (4)
  • app/lib/methods/helpers/helpers.ts (4 hunks)
  • app/views/RoomActionsView/index.tsx (1 hunks)
  • app/views/RoomInfoView/index.tsx (1 hunks)
  • app/views/RoomView/index.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
app/views/RoomActionsView/index.tsx (1)
app/lib/services/restApi.ts (1)
  • getUserInfo (1067-1070)
app/views/RoomView/index.tsx (1)
app/lib/services/restApi.ts (1)
  • getUserInfo (1067-1070)
app/views/RoomInfoView/index.tsx (1)
app/lib/services/restApi.ts (1)
  • getUserInfo (1067-1070)
app/lib/methods/helpers/helpers.ts (4)
app/definitions/IRoom.ts (1)
  • IRoom (18-65)
app/definitions/ISubscription.ts (1)
  • ISubscription (40-119)
app/sagas/deepLinking.js (4)
  • room (69-69)
  • room (222-222)
  • uid (226-226)
  • item (71-76)
app/definitions/IMessage.ts (1)
  • IUserMessage (23-27)
🔇 Additional comments (4)
app/views/RoomView/index.tsx (1)

616-637: Guard around roomUserId correctly prevents invalid getUserInfo calls

Wrapping the state update and getUserInfo call in if (roomUserId) is a good safety net with the new getUidDirectMessage behavior, avoiding API calls and header updates when the DM target can’t be resolved, without changing the successful-path behavior.

app/lib/methods/helpers/helpers.ts (1)

7-29: TRoomLike, isGroupChat, and getRoomAvatar typings/logic look solid

The TRoomLike helper type cleanly abstracts the overlap between IRoom and ISubscription, and the updated isGroupChat/getRoomAvatar implementations are null-safe and align with the “> 2 participants ⇒ group chat” rule, with sensible string fallbacks when metadata is missing.

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

164-183: Guarding roomUserId in loadUser matches new helper semantics

The if (roomUserId) guard before getUserInfo cleanly aligns this code with the stricter getUidDirectMessage contract and avoids sending users.info requests with undefined IDs, while preserving the existing role-enrichment behavior for valid DMs.

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

465-482: updateRoomMember now safely skips invalid DM member lookups

The combination of !isGroupChat(room) and if (roomUserId) before calling getUserInfo is a good tightening: it prevents requests with undefined IDs and intentionally avoids treating group DMs as single‑member conversations, while keeping the successful fetch path unchanged.

Comment thread app/lib/methods/helpers/helpers.ts Outdated
Comment thread app/lib/methods/helpers/helpers.ts Outdated
Comment thread app/lib/methods/helpers/helpers.ts Outdated
Comment thread app/lib/methods/helpers/helpers.ts
Comment thread app/lib/methods/helpers/helpers.ts Outdated
Comment thread app/lib/methods/helpers/helpers.ts Outdated
Comment thread app/views/RoomActionsView/index.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
app/lib/hooks/useUserData.ts (1)

24-24: Unsafe type assertion bypasses undefined handling.

getUidDirectMessage returns string | undefined, but line 24 casts the result to string. If the function returns undefined, this could lead to runtime issues when setting state with an invalid uid.

Apply this diff to handle the undefined case safely:

-				const uid = (await getUidDirectMessage(room)) as string;
+				const uid = await getUidDirectMessage(room);
+				if (!uid) {
+					return;
+				}
🧹 Nitpick comments (1)
app/lib/methods/helpers/helpers.ts (1)

8-12: Consider refining the TRoomLike type definition.

Using Pick<IRoom | ISubscription, ...> with a union type may not work as expected. TypeScript will only pick properties that exist in both types. Consider using a union of Picks instead for more accurate typing:

-type TRoomLike = Pick<IRoom | ISubscription, 'uids' | 'usernames' | 'prid' | 'fname' | 'name'> & {
-	t?: string;
-	rid?: string;
-	federated?: boolean;
-};
+type TRoomLike = (Pick<IRoom, 'uids' | 'usernames' | 'prid' | 'fname' | 'name'> | Pick<ISubscription, 'uids' | 'usernames' | 'prid' | 'fname' | 'name'>) & {
+	t?: string;
+	rid?: string;
+	federated?: boolean;
+};

Alternatively, define it as a minimal interface:

type TRoomLike = {
	uids?: string[];
	usernames?: string[];
	prid?: string;
	fname?: string;
	name?: string;
	t?: string;
	rid?: string;
	federated?: boolean;
};
📜 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 60aeaf3 and 5de3fb5.

📒 Files selected for processing (7)
  • app/containers/CallHeader.tsx (1 hunks)
  • app/containers/InAppNotification/IncomingCallNotification/index.tsx (1 hunks)
  • app/containers/InAppNotification/NotifierComponent.tsx (1 hunks)
  • app/containers/RoomItem/interfaces.ts (4 hunks)
  • app/lib/hooks/useUserData.ts (1 hunks)
  • app/lib/methods/helpers/helpers.ts (4 hunks)
  • app/views/RoomInfoView/index.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/views/RoomInfoView/index.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
app/lib/hooks/useUserData.ts (2)
app/sagas/encryption.js (2)
  • user (21-21)
  • user (94-94)
app/actions/login.ts (1)
  • setUser (91-96)
app/lib/methods/helpers/helpers.ts (3)
app/definitions/IRoom.ts (1)
  • IRoom (18-65)
app/definitions/ISubscription.ts (1)
  • ISubscription (40-119)
app/definitions/IMessage.ts (1)
  • IUserMessage (23-27)
🔇 Additional comments (14)
app/containers/InAppNotification/NotifierComponent.tsx (1)

26-26: LGTM! Optional avatar property is well-handled.

The change to make avatar optional aligns with the broader type-safety improvements. The fallback logic at line 82 (avatar = name) ensures a value is always provided to the Avatar component.

app/lib/hooks/useUserData.ts (1)

10-16: LGTM! Explicit state type improves type safety.

The explicit type annotation for the state correctly reflects that avatar is optional while other fields are required.

app/containers/RoomItem/interfaces.ts (1)

44-44: LGTM! Consistent optional avatar handling across interfaces.

All avatar-related properties and return types have been correctly updated to be optional, aligning with the getRoomAvatar helper that returns string | undefined. This ensures type consistency across the codebase.

Also applies to: 97-97, 106-106, 152-152

app/lib/methods/helpers/helpers.ts (9)

17-19: LGTM! Well-typed with proper null-safety.

The function correctly handles undefined input and uses optional chaining to safely access properties. The JSDoc provides clear documentation.


24-29: LGTM! Properly returns undefined for missing avatars.

The function now correctly returns string | undefined and uses optional chaining throughout. This addresses the previous feedback about not returning empty strings.


34-58: LGTM! Improved type safety with undefined returns.

The function now consistently returns undefined instead of null and handles edge cases properly. The explicit || undefined at line 57 ensures the return type contract is maintained.


63-80: LGTM! Well-guarded string returns.

The function uses optional chaining and provides empty string fallbacks appropriately. The federated room handling and special character logic are properly typed.


85-88: LGTM! Clean implementation with proper fallback.

The function correctly uses the IUserMessage type and provides an empty string fallback for missing name/username.


93-106: LGTM! Robust error handling and boolean return.

The function properly handles the feature flag check, permission verification, and includes try-catch with a safe false fallback.


111-115: LGTM! Null-safe with nullish coalescing.

The function correctly uses nullish coalescing (?? 0) to handle undefined unread values and properly types the parameter as Partial<ISubscription>.


120-124: LGTM! Simple and correctly typed.

The function accepts a string parameter and performs the role check safely with array fallback.


132-157: LGTM! Comprehensive permission checking with proper error handling.

The function now has explicit typing for the parameter and return type. The logic properly merges room and user roles, and the error handling returns safe defaults. Once the type assertion at line 141 is fixed, this will be fully type-safe.

app/containers/CallHeader.tsx (1)

22-22: LGTM! Consistent with avatar optionality pattern.

Making the avatar property optional aligns with the broader changes across the codebase. The AvatarContainer component at line 74 receives the optional avatar via the text prop, which should handle undefined gracefully.

app/containers/InAppNotification/IncomingCallNotification/index.tsx (1)

28-28: LGTM! Avatar optionality properly threaded through component hierarchy.

Both the notification payload and the IncomingCallHeader props correctly define avatar as optional. This allows the component to gracefully handle cases where avatar data is unavailable, and the value flows correctly to the CallHeader component at line 79.

Also applies to: 36-36

Comment thread app/lib/methods/helpers/helpers.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (5)
app/lib/methods/helpers/helpers.ts (5)

21-29: Group avatar identifier logic generally looks good; optional refinement

Returning undefined instead of a fallback empty string when there’s no avatar id is a good alignment with the previous review feedback. One small thing to double‑check: the extra room?.uids && room?.usernames guard means that group rooms detected via uids but missing usernames (or vice versa) will skip the group‑avatar branch and fall back to fname/name. If that’s not intentional, consider basing the key on whichever of uids or usernames is available.


34-58: getUidDirectMessage flow is solid; consider guarding against missing login.user

The control flow covers null rooms, itsMe, legacy rid DMs, and group DMs cleanly, and the undefined returns give clear “no DM target” semantics. The only potential fragility is destructuring const { id: userId } = reduxStore.getState().login.user; which will throw if login.user is ever undefined when this helper runs. If that’s possible, you can make this safer with:

-	const { id: userId } = reduxStore.getState().login.user;
+	const userId = reduxStore.getState().login.user?.id;

The rest of the logic already handles a falsy userId correctly.


63-80: getRoomTitle covers the main scenarios; minor simplification possible

The ordering (federated → group usernames → special‑char rooms → DM/real‑name logic) reads well and guarantees a string result. Since TRoomLike already includes an optional federated flag, you could simplify the first branch to if (room?.federated === true) and drop the 'federated' in room check without changing behavior.


108-115: isRead logic seems intentional; comment is slightly misleading

The implementation treats items as unread only when they are not archived, are open, and have unread > 0 or alert === true, which is a reasonable definition. The comment on Line 112 (“not opened”) doesn’t match item.open === true, so it may be worth updating the comment (or condition, if the comment is the correct intent) to avoid confusion later.


132-158: hasPermission is now strongly typed and safer; unify logging style

Using db.get<TSubscriptionModel>('subscriptions') and accessing room.roles directly removes the previous as any escape hatch and improves type safety. The merged roomRoles/userRoles set plus the per‑permission mapping is clear. One minor nit: this function mixes console.log (room not found) with log(e) in the catch; consider using the same log helper for both to keep logging consistent.

📜 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 5de3fb5 and 37a1e53.

📒 Files selected for processing (1)
  • app/lib/methods/helpers/helpers.ts (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/lib/methods/helpers/helpers.ts (3)
app/definitions/IRoom.ts (1)
  • IRoom (18-65)
app/definitions/ISubscription.ts (2)
  • ISubscription (40-119)
  • TSubscriptionModel (121-124)
app/definitions/IMessage.ts (1)
  • IUserMessage (23-27)
🔇 Additional comments (4)
app/lib/methods/helpers/helpers.ts (4)

7-19: TRoomLike abstraction and isGroupChat typing look appropriate

Combining IRoom/ISubscription into TRoomLike and accepting Partial<TRoomLike> | undefined in isGroupChat gives you the flexibility you need across helpers while keeping the implementation null‑safe; the boolean logic for “more than 2 participants” is clear and consistent.


85-88: getSenderName correctly matches IUserMessage and settings

Typing sender as IUserMessage and switching between name/username based on UI_Use_Real_Name, with a safe '' fallback, is exactly what you want here.


93-106: canAutoTranslate is defensive and respects role-based permissions

The early exit on AutoTranslate_Enabled, intersection of permissions['auto-translate'] with user.roles, and the try/catch that falls back to false all make this helper robust without surprising callers.


120-124: hasRole helper is simple and now properly typed

Explicitly typing role: string and reading from login.user.roles with a safe fallback array keeps this helper straightforward and predictable.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
app/containers/RoomItem/index.tsx (1)

30-31: Move null-coercion to variable declaration for consistency.

Line 31 constructs testID using the raw name value, which produces "rooms-list-view-item-undefined" when getRoomTitle returns undefined. Meanwhile, line 61 coerces name to an empty string. This inconsistency can break test selectors and accessibility tools.

Apply this diff to unify the handling and improve the fallback:

-const name = getRoomTitle(item);
+const name = getRoomTitle(item) || 'Unknown Room';
 const testID = `rooms-list-view-item-${name}`;

and remove the redundant coercion at the prop site:

-			name={name || ''}
+			name={name}

Optional: If you prefer an empty string for the name prop specifically, you can still unify at declaration and override at prop time, but a descriptive fallback like 'Unknown Room' improves UX when room titles are missing.

Also applies to: 61-61

📜 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 37a1e53 and 0db4057.

📒 Files selected for processing (10)
  • app/containers/RoomItem/index.tsx (1 hunks)
  • app/containers/RoomItem/interfaces.ts (4 hunks)
  • app/lib/methods/helpers/helpers.ts (4 hunks)
  • app/views/AddExistingChannelView/index.tsx (2 hunks)
  • app/views/CreateDiscussionView/SelectChannel.tsx (2 hunks)
  • app/views/CreateDiscussionView/SelectUsers.tsx (2 hunks)
  • app/views/ForwardMessageView/SelectPersonOrChannel.tsx (2 hunks)
  • app/views/RoomInfoEditView/index.tsx (3 hunks)
  • app/views/RoomView/index.tsx (3 hunks)
  • app/views/ShareView/Header.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • app/views/AddExistingChannelView/index.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/containers/RoomItem/interfaces.ts
  • app/views/RoomView/index.tsx
  • app/lib/methods/helpers/helpers.ts
🧰 Additional context used
🧬 Code graph analysis (4)
app/views/CreateDiscussionView/SelectChannel.tsx (1)
app/lib/methods/helpers/helpers.ts (1)
  • getRoomTitle (63-80)
app/views/CreateDiscussionView/SelectUsers.tsx (1)
app/lib/methods/helpers/helpers.ts (1)
  • getRoomTitle (63-80)
app/containers/RoomItem/index.tsx (1)
app/sagas/deepLinking.js (1)
  • name (62-62)
app/views/ForwardMessageView/SelectPersonOrChannel.tsx (1)
app/lib/methods/helpers/helpers.ts (1)
  • getRoomTitle (63-80)
🪛 Biome (2.1.2)
app/views/RoomInfoEditView/index.tsx

[error] 453-453: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)


[error] 454-454: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (5)
app/views/ShareView/Header.tsx (1)

96-96: LGTM! Proper null-safety guard.

The fallback to an empty string ensures setTitle always receives a defined string value when getRoomTitle returns undefined, preventing potential UI issues.

app/views/CreateDiscussionView/SelectChannel.tsx (1)

32-32: LGTM! Consistent null-safety pattern.

Both mappings now guarantee string values for the text property by falling back to an empty string when getRoomTitle returns undefined.

Also applies to: 70-70

app/views/CreateDiscussionView/SelectUsers.tsx (1)

36-36: LGTM! Proper string coercion.

The fallback ensures the text property always receives a string value, aligning with the TypeScript migration's stricter return types.

Also applies to: 69-69

app/views/ForwardMessageView/SelectPersonOrChannel.tsx (1)

32-32: LGTM! Consistent with project-wide pattern.

Both room option mappings now provide string fallbacks, ensuring the UI components receive defined text values.

Also applies to: 65-65

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

95-95: LGTM! Defensive string initialization.

The fallback ensures the form name field always initializes with a string value, preventing undefined from being set.

Comment thread app/views/RoomInfoEditView/index.tsx Outdated
@DSingh0304
DSingh0304 requested a review from Rohit3523 November 28, 2025 19:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
app/views/RoomInfoEditView/index.tsx (1)

452-456: LGTM: Proper key props added to array elements.

The addition of unique key props resolves the React warning and ensures proper reconciliation during re-renders. This addresses the past review comment.

🧹 Nitpick comments (1)
app/lib/methods/helpers/helpers.ts (1)

126-159: LGTM: Comprehensive permission checking with proper database typing.

The function correctly:

  • Types the subscriptions collection as TSubscriptionModel (line 136)
  • Safely accesses room.roles with a null check (lines 141-143)
  • Returns definite false values on errors (lines 146, 157)
  • Maps permissions with proper optional chaining (line 154)

The return type Promise<(boolean | undefined)[]> accurately reflects that individual permission checks can be undefined when the permission array itself is undefined.

💡 Optional: Consider returning definite booleans to simplify call sites

Currently, callers must add || false to ensure boolean values. You could simplify this by having hasPermission return Promise<boolean[]> directly:

-return permissions.map(permission => permission?.some(r => mergedRoles.includes(r)));
+return permissions.map(permission => permission?.some(r => mergedRoles.includes(r)) || false);

This would eliminate the need for || false at the ~15 call sites throughout the codebase. However, the current approach is also valid and makes the undefined possibility explicit at call sites.

📜 Review details

Configuration used: Organization 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 17fdb89 and 3e698ad.

📒 Files selected for processing (7)
  • app/containers/MessageActions/index.tsx (1 hunks)
  • app/lib/methods/helpers/helpers.ts (4 hunks)
  • app/views/RoomActionsView/index.tsx (5 hunks)
  • app/views/RoomInfoEditView/index.tsx (3 hunks)
  • app/views/RoomView/RightButtons.tsx (1 hunks)
  • app/views/RoomView/index.tsx (3 hunks)
  • app/views/ShareView/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/views/RoomView/index.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-17T15:56:14.049Z
Learnt from: OtavioStasiak
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6499
File: app/containers/ServerItem/index.tsx:34-36
Timestamp: 2025-12-17T15:56:14.049Z
Learning: In the Rocket.Chat React Native codebase, for radio button components on iOS, include the selection state ("Selected"/"Unselected") in the accessibilityLabel instead of using accessibilityState={{ checked: hasCheck }}, because iOS VoiceOver has known issues with accessibilityRole="radio" + accessibilityState that prevent correct state announcement.

Applied to files:

  • app/views/RoomInfoEditView/index.tsx
  • app/lib/methods/helpers/helpers.ts
🧬 Code graph analysis (4)
app/views/RoomActionsView/index.tsx (2)
app/lib/methods/helpers/helpers.ts (1)
  • hasPermission (132-159)
app/lib/services/restApi.ts (1)
  • getUserInfo (1096-1099)
app/views/RoomView/RightButtons.tsx (1)
app/reducers/permissions.ts (1)
  • permissions (13-25)
app/views/RoomInfoEditView/index.tsx (3)
app/stacks/types.ts (1)
  • ChatsStackParamList (22-188)
app/stacks/MasterDetailStack/types.ts (1)
  • ModalStackParamList (30-210)
app/lib/methods/helpers/helpers.ts (1)
  • getRoomTitle (63-80)
app/lib/methods/helpers/helpers.ts (3)
app/definitions/IRoom.ts (1)
  • IRoom (18-65)
app/definitions/ISubscription.ts (2)
  • ISubscription (40-119)
  • TSubscriptionModel (121-124)
app/definitions/IMessage.ts (1)
  • IUserMessage (23-27)
🔇 Additional comments (19)
app/containers/MessageActions/index.tsx (1)

129-136: LGTM: Defensive boolean coercion ensures type safety.

The || false fallbacks correctly handle the possibility of undefined values from hasPermission, ensuring all permission flags are definite booleans. This pattern is consistently applied across all permission checks.

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

358-365: LGTM: Consistent permission handling.

The || false fallback aligns with the broader pattern across the codebase to ensure definite boolean values from permission checks.

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

186-198: LGTM: Proper boolean handling for file upload permission.

The || false fallback ensures canUploadFile receives a definite boolean value, maintaining consistency with permission-handling patterns throughout the PR.

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

95-95: LGTM: Safe string fallback for room title.

The || '' fallback correctly handles the case where getRoomTitle returns undefined, ensuring the form field receives a definite string value.

app/views/RoomActionsView/index.tsx (6)

332-340: LGTM: Consistent permission result handling.

The || false fallback ensures canEdit is a definite boolean, consistent with permission-handling patterns across the codebase.


342-350: LGTM: Consistent permission result handling.

The || false fallback ensures canCreateTeam is a definite boolean, consistent with permission-handling patterns across the codebase.


352-360: LGTM: Consistent permission result handling.

The || false fallback is properly applied in both server version paths, ensuring hasMoveToTeamPermission always returns a definite boolean.


362-370: LGTM: Consistent permission result handling.

The || false fallback ensures canConvertTeam is a definite boolean, consistent with permission-handling patterns across the codebase.


372-380: LGTM: Consistent permission result handling.

The || false fallback ensures canToggleEncryption is a definite boolean, consistent with permission-handling patterns across the codebase.


465-483: LGTM: Critical null-safety guard prevents invalid API calls.

The guard at line 471 is essential—it prevents calling getUserInfo with undefined since getUidDirectMessage now returns string | undefined. This avoids potential runtime errors from invalid API requests.

app/lib/methods/helpers/helpers.ts (9)

7-12: LGTM: Well-designed type alias for room-like objects.

The TRoomLike type effectively captures the common fields needed across IRoom and ISubscription, providing a flexible foundation for the helper functions.


14-19: LGTM: Defensive typing allows safe partial objects.

Using Partial<TRoomLike> | undefined appropriately handles incomplete or missing room data, with nullish coalescing at line 18 providing a safe boolean default.


21-29: LGTM: Explicit undefined return improves type safety.

The string | undefined return type accurately reflects that the avatar may not be available. The optional chaining throughout ensures safe access.


31-58: LGTM: Refined typing and explicit undefined handling.

The parameter type correctly models the input shape (allowing null and the itsMe flag), and the explicit conversion to undefined at line 38 provides consistent behavior. The fallback at line 57 ensures a definite result when possible.


60-80: LGTM: Comprehensive room title logic with defensive access.

The function correctly handles federated rooms, group chats, and special character settings, using optional chaining throughout to safely access potentially undefined properties.


82-88: LGTM: Clear sender name resolution with proper typing.

The function correctly respects the real name setting and provides a safe empty string fallback when both name and username are unavailable.


90-106: LGTM: Explicit boolean return with comprehensive error handling.

The function explicitly returns false in all error and disabled cases, ensuring the return type is always a definite boolean.


108-115: LGTM: Nullish coalescing ensures safe unread count access.

The item.unread ?? 0 pattern at line 113 safely handles potentially undefined unread counts, and the explicit boolean logic is clear.


117-124: LGTM: Simple and correct role check implementation.

The function properly accesses user roles with a safe fallback and uses a clear array inclusion check.

@DSingh0304 DSingh0304 closed this Feb 22, 2026
@DSingh0304
DSingh0304 force-pushed the fix/typescript-migration-helpers-6781 branch from 3e698ad to 895ebf0 Compare February 22, 2026 08:48
@DSingh0304
DSingh0304 deleted the fix/typescript-migration-helpers-6781 branch February 22, 2026 08:48
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.

Bug Fix: TypeScript migration for helpers.ts

2 participants