fix: typescript migration helpers 6781 - #6796
Conversation
WalkthroughAdds 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
app/lib/methods/helpers/helpers.ts (2)
31-88:getUidDirectMessageandgetRoomTitleimprovements; consider guarding missing login userThe new
getUidDirectMessagebehavior (explicitstring | undefined,itsMesupport, group-chat early return) andgetRoomTitle’s federated/DM-aware logic nicely tighten nullability and make call sites safer.One potential hardening: destructuring from
reduxStore.getState().login.userwill throw iflogin.useris 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 nitsThe revised
canAutoTranslate,isRead,hasRole, andhasPermissionimplementations all look correct and more null-safe:
canAutoTranslatenow cleanly bails out on settings/permission misconfiguration and logs unexpected errors.isRead’s use ofunread ?? 0andalert === trueavoids undefined pitfalls.hasPermissioncorrectly 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 matchitem.open === true; clarifying that comment to “item is not archived and is open” would avoid confusion.- In the
hasPermissioncatch block where the room isn’t found, using the sharedloghelper (or includingridin the message) instead of a bareconsole.logwould 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.
📒 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 aroundroomUserIdcorrectly prevents invalidgetUserInfocallsWrapping the state update and
getUserInfocall inif (roomUserId)is a good safety net with the newgetUidDirectMessagebehavior, 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, andgetRoomAvatartypings/logic look solidThe
TRoomLikehelper type cleanly abstracts the overlap betweenIRoomandISubscription, and the updatedisGroupChat/getRoomAvatarimplementations 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: GuardingroomUserIdinloadUsermatches new helper semanticsThe
if (roomUserId)guard beforegetUserInfocleanly aligns this code with the strictergetUidDirectMessagecontract and avoids sendingusers.inforequests with undefined IDs, while preserving the existing role-enrichment behavior for valid DMs.app/views/RoomActionsView/index.tsx (1)
465-482:updateRoomMembernow safely skips invalid DM member lookupsThe combination of
!isGroupChat(room)andif (roomUserId)before callinggetUserInfois 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.
There was a problem hiding this comment.
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 bypassesundefinedhandling.
getUidDirectMessagereturnsstring | undefined, but line 24 casts the result tostring. If the function returnsundefined, this could lead to runtime issues when setting state with an invaliduid.Apply this diff to handle the
undefinedcase 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.
📒 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
avataroptional 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
avataris 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
getRoomAvatarhelper that returnsstring | 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
undefinedinput and uses optional chaining to safely access properties. The JSDoc provides clear documentation.
24-29: LGTM! Properly returnsundefinedfor missing avatars.The function now correctly returns
string | undefinedand uses optional chaining throughout. This addresses the previous feedback about not returning empty strings.
34-58: LGTM! Improved type safety withundefinedreturns.The function now consistently returns
undefinedinstead ofnulland handles edge cases properly. The explicit|| undefinedat 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
IUserMessagetype 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
falsefallback.
111-115: LGTM! Null-safe with nullish coalescing.The function correctly uses nullish coalescing (
?? 0) to handle undefinedunreadvalues and properly types the parameter asPartial<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
avatarproperty optional aligns with the broader changes across the codebase. TheAvatarContainercomponent at line 74 receives the optional avatar via thetextprop, which should handleundefinedgracefully.app/containers/InAppNotification/IncomingCallNotification/index.tsx (1)
28-28: LGTM! Avatar optionality properly threaded through component hierarchy.Both the notification payload and the
IncomingCallHeaderprops correctly defineavataras optional. This allows the component to gracefully handle cases where avatar data is unavailable, and the value flows correctly to theCallHeadercomponent at line 79.Also applies to: 36-36
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
app/lib/methods/helpers/helpers.ts (5)
21-29: Group avatar identifier logic generally looks good; optional refinementReturning
undefinedinstead 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 extraroom?.uids && room?.usernamesguard means that group rooms detected viauidsbut missingusernames(or vice versa) will skip the group‑avatar branch and fall back tofname/name. If that’s not intentional, consider basing the key on whichever ofuidsorusernamesis available.
34-58: getUidDirectMessage flow is solid; consider guarding against missing login.userThe control flow covers
nullrooms,itsMe, legacyridDMs, and group DMs cleanly, and theundefinedreturns give clear “no DM target” semantics. The only potential fragility is destructuringconst { id: userId } = reduxStore.getState().login.user;which will throw iflogin.useris everundefinedwhen 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
userIdcorrectly.
63-80: getRoomTitle covers the main scenarios; minor simplification possibleThe ordering (federated → group usernames → special‑char rooms → DM/real‑name logic) reads well and guarantees a string result. Since
TRoomLikealready includes an optionalfederatedflag, you could simplify the first branch toif (room?.federated === true)and drop the'federated' in roomcheck without changing behavior.
108-115: isRead logic seems intentional; comment is slightly misleadingThe implementation treats items as unread only when they are not archived, are open, and have
unread > 0oralert === true, which is a reasonable definition. The comment on Line 112 (“not opened”) doesn’t matchitem.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 styleUsing
db.get<TSubscriptionModel>('subscriptions')and accessingroom.rolesdirectly removes the previousas anyescape hatch and improves type safety. The mergedroomRoles/userRolesset plus the per‑permission mapping is clear. One minor nit: this function mixesconsole.log(room not found) withlog(e)in the catch; consider using the sameloghelper 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.
📒 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 appropriateCombining
IRoom/ISubscriptionintoTRoomLikeand acceptingPartial<TRoomLike> | undefinedinisGroupChatgives 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 settingsTyping
senderasIUserMessageand switching betweenname/usernamebased onUI_Use_Real_Name, with a safe''fallback, is exactly what you want here.
93-106: canAutoTranslate is defensive and respects role-based permissionsThe early exit on
AutoTranslate_Enabled, intersection ofpermissions['auto-translate']withuser.roles, and the try/catch that falls back tofalseall make this helper robust without surprising callers.
120-124: hasRole helper is simple and now properly typedExplicitly typing
role: stringand reading fromlogin.user.roleswith a safe fallback array keeps this helper straightforward and predictable.
There was a problem hiding this comment.
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
testIDusing the rawnamevalue, which produces"rooms-list-view-item-undefined"whengetRoomTitlereturnsundefined. Meanwhile, line 61 coercesnameto 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.
📒 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
setTitlealways receives a defined string value whengetRoomTitlereturnsundefined, 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
textproperty by falling back to an empty string whengetRoomTitlereturnsundefined.Also applies to: 70-70
app/views/CreateDiscussionView/SelectUsers.tsx (1)
36-36: LGTM! Proper string coercion.The fallback ensures the
textproperty 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
undefinedfrom being set.
There was a problem hiding this comment.
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
keyprops 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.roleswith a null check (lines 141-143)- Returns definite
falsevalues 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
|| falseto ensure boolean values. You could simplify this by havinghasPermissionreturnPromise<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
|| falseat 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.
📒 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.tsxapp/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
|| falsefallbacks correctly handle the possibility ofundefinedvalues fromhasPermission, 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
|| falsefallback 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
|| falsefallback ensurescanUploadFilereceives 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 wheregetRoomTitlereturnsundefined, ensuring the form field receives a definite string value.app/views/RoomActionsView/index.tsx (6)
332-340: LGTM: Consistent permission result handling.The
|| falsefallback ensurescanEditis a definite boolean, consistent with permission-handling patterns across the codebase.
342-350: LGTM: Consistent permission result handling.The
|| falsefallback ensurescanCreateTeamis a definite boolean, consistent with permission-handling patterns across the codebase.
352-360: LGTM: Consistent permission result handling.The
|| falsefallback is properly applied in both server version paths, ensuringhasMoveToTeamPermissionalways returns a definite boolean.
362-370: LGTM: Consistent permission result handling.The
|| falsefallback ensurescanConvertTeamis a definite boolean, consistent with permission-handling patterns across the codebase.
372-380: LGTM: Consistent permission result handling.The
|| falsefallback ensurescanToggleEncryptionis 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
getUserInfowithundefinedsincegetUidDirectMessagenow returnsstring | 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
TRoomLiketype effectively captures the common fields needed acrossIRoomandISubscription, providing a flexible foundation for the helper functions.
14-19: LGTM: Defensive typing allows safe partial objects.Using
Partial<TRoomLike> | undefinedappropriately 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 | undefinedreturn 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
nulland theitsMeflag), and the explicit conversion toundefinedat 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
falsein 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 ?? 0pattern 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.
3e698ad to
895ebf0
Compare
Proposed changes
This PR completes the TypeScript migration for
app/lib/methods/helpers/helpers.tsby removing the@ts-nocheckdirective and adding proper type annotations to all helper functions.Key changes:
@ts-nocheckdirective from helpers.tsTRoomLiketype alias to handle bothIRoomandISubscriptionobjects flexiblyundefinedinputs gracefully, ensuring type safetyRoomActionsView,RoomInfoView,RoomView) to prevent passingundefinedvalues togetUserInfoAll functions now have proper type annotations:
isGroupChat,getRoomAvatar,getUidDirectMessage,getRoomTitle,getSenderName,canAutoTranslate,isRead,hasRole,hasPermissionIssue(s)
Fixes #6781
How to test or reproduce
yarn tsc --noEmitto verify TypeScript compilation passes without errorsyarn lint app/lib/methods/helpers/helpers.tsto verify ESLint passesScreenshots
N/A - Type-only changes, no visual modifications
Types of changes
Checklist
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:
Summary by CodeRabbit
Bug Fixes
Refactor
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.