diff --git a/native/account/register-panel.react.js b/native/account/register-panel.react.js --- a/native/account/register-panel.react.js +++ b/native/account/register-panel.react.js @@ -52,11 +52,12 @@ import { nativeNotificationsSessionCreator } from '../utils/crypto-utils.js'; import { type StateContainer } from '../utils/state-container.js'; -export type RegisterState = { - +usernameInputText: string, - +passwordInputText: string, - +confirmPasswordInputText: string, +type WritableRegisterState = { + usernameInputText: string, + passwordInputText: string, + confirmPasswordInputText: string, }; +export type RegisterState = $ReadOnly; type BaseProps = { +setActiveAlert: (activeAlert: boolean) => void, +opacityValue: Animated.Node, @@ -240,7 +241,7 @@ }; onChangePasswordInputText = (text: string) => { - const stateUpdate = {}; + const stateUpdate: Partial = {}; stateUpdate.passwordInputText = text; if (this.passwordBeingAutoFilled) { this.passwordBeingAutoFilled = false; diff --git a/native/avatars/avatar.react.js b/native/avatars/avatar.react.js --- a/native/avatars/avatar.react.js +++ b/native/avatars/avatar.react.js @@ -17,6 +17,7 @@ xxLargeAvatarSize, } from './avatar-constants.js'; import Multimedia from '../media/multimedia.react.js'; +import type { ViewStyle } from '../types/styles.js'; type Props = { +avatarInfo: ResolvedClientAvatar, @@ -42,7 +43,10 @@ }, [size]); const emojiContainerStyle = React.useMemo(() => { - const containerStyles = [styles.emojiContainer, containerSizeStyle]; + const containerStyles: Array = [ + styles.emojiContainer, + containerSizeStyle, + ]; if (avatarInfo.type === 'emoji') { const backgroundColor = { backgroundColor: `#${avatarInfo.color}` }; containerStyles.push(backgroundColor); diff --git a/native/calendar/calendar.react.js b/native/calendar/calendar.react.js --- a/native/calendar/calendar.react.js +++ b/native/calendar/calendar.react.js @@ -902,7 +902,7 @@ return; } - const visibleEntries = {}; + const visibleEntries: { [string]: boolean } = {}; for (const token of info.viewableItems) { if (token.item.itemType === 'entryInfo') { visibleEntries[entryKey(token.item.entryInfo)] = true; diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js --- a/native/chat/chat-input-bar.react.js +++ b/native/chat/chat-input-bar.react.js @@ -134,7 +134,11 @@ import { useSelector } from '../redux/redux-utils.js'; import { type Colors, useStyles, useColors } from '../themes/colors.js'; import type { LayoutEvent, ImagePasteEvent } from '../types/react-native.js'; -import { type AnimatedViewStyle, AnimatedView } from '../types/styles.js'; +import { + type AnimatedViewStyle, + AnimatedView, + type ViewStyle, +} from '../types/styles.js'; import Alert from '../utils/alert.js'; import { runTiming } from '../utils/animation-utils.js'; import { exitEditAlert } from '../utils/edit-messages-utils.js'; @@ -818,7 +822,9 @@ ); const threadColor = `#${this.props.threadInfo.color}`; - const expandoButtonsViewStyle = [this.props.styles.innerExpandoButtons]; + const expandoButtonsViewStyle: Array = [ + this.props.styles.innerExpandoButtons, + ]; if (this.isEditMode()) { expandoButtonsViewStyle.push({ display: 'none' }); } diff --git a/native/chat/compose-subchannel.react.js b/native/chat/compose-subchannel.react.js --- a/native/chat/compose-subchannel.react.js +++ b/native/chat/compose-subchannel.react.js @@ -220,7 +220,7 @@ ], ); - const existingThreads = React.useMemo(() => { + const existingThreads: $ReadOnlyArray = React.useMemo(() => { if (userInfoInputIDs.length === 0) { return []; } diff --git a/native/chat/composed-message.react.js b/native/chat/composed-message.react.js --- a/native/chat/composed-message.react.js +++ b/native/chat/composed-message.react.js @@ -33,7 +33,11 @@ import { InputStateContext } from '../input/input-state.js'; import { useColors } from '../themes/colors.js'; import type { ChatMessageInfoItemWithHeight } from '../types/chat-types.js'; -import { type AnimatedStyleObj, AnimatedView } from '../types/styles.js'; +import { + type AnimatedStyleObj, + type ViewStyle, + AnimatedView, +} from '../types/styles.js'; import { useNavigateToUserProfileBottomSheet } from '../user-profile/user-profile-utils.js'; type SwipeOptions = 'reply' | 'sidebar' | 'both' | 'none'; @@ -294,7 +298,7 @@ ]); const viewStyle = React.useMemo(() => { - const baseStyle = [styles.alignment]; + const baseStyle: Array = [styles.alignment]; if (__DEV__) { return baseStyle; } diff --git a/native/chat/message-results-screen.react.js b/native/chat/message-results-screen.react.js --- a/native/chat/message-results-screen.react.js +++ b/native/chat/message-results-screen.react.js @@ -16,6 +16,7 @@ import { useHeightMeasurer } from './chat-context.js'; import type { ChatNavigationProp } from './chat.react'; +import type { NativeChatMessageItem } from './message-data.react.js'; import MessageResult from './message-result.react.js'; import type { NavigationRoute } from '../navigation/route-names'; import { useSelector } from '../redux/redux-utils.js'; @@ -68,41 +69,42 @@ messageListData(threadInfo.id, translatedMessageResults), ); - const sortedUniqueChatMessageInfoItems = React.useMemo(() => { - if (!chatMessageInfos) { - return []; - } - - const chatMessageInfoItems = chatMessageInfos.filter( - item => - item.itemType === 'message' && - item.isPinned && - !isInvalidPinSourceForThread(item.messageInfo, threadInfo), - ); - - // By the nature of using messageListData and passing in - // the desired translatedMessageResults as additional - // messages, we will have duplicate ChatMessageInfoItems. - const uniqueChatMessageInfoItemsMap = new Map(); - chatMessageInfoItems.forEach( - item => - item.messageInfo && - item.messageInfo.id && - uniqueChatMessageInfoItemsMap.set(item.messageInfo.id, item), - ); + const sortedUniqueChatMessageInfoItems: $ReadOnlyArray = + React.useMemo(() => { + if (!chatMessageInfos) { + return []; + } + + const chatMessageInfoItems = chatMessageInfos.filter( + item => + item.itemType === 'message' && + item.isPinned && + !isInvalidPinSourceForThread(item.messageInfo, threadInfo), + ); - // Push the items in the order they appear in the rawMessageResults - // since the messages fetched from the server are already sorted - // in the order of pin_time (newest first). - const sortedChatMessageInfoItems = []; - for (let i = 0; i < rawMessageResults.length; i++) { - sortedChatMessageInfoItems.push( - uniqueChatMessageInfoItemsMap.get(rawMessageResults[i].id), + // By the nature of using messageListData and passing in + // the desired translatedMessageResults as additional + // messages, we will have duplicate ChatMessageInfoItems. + const uniqueChatMessageInfoItemsMap = new Map(); + chatMessageInfoItems.forEach( + item => + item.messageInfo && + item.messageInfo.id && + uniqueChatMessageInfoItemsMap.set(item.messageInfo.id, item), ); - } - return sortedChatMessageInfoItems.filter(Boolean); - }, [chatMessageInfos, rawMessageResults, threadInfo]); + // Push the items in the order they appear in the rawMessageResults + // since the messages fetched from the server are already sorted + // in the order of pin_time (newest first). + const sortedChatMessageInfoItems = []; + for (let i = 0; i < rawMessageResults.length; i++) { + sortedChatMessageInfoItems.push( + uniqueChatMessageInfoItemsMap.get(rawMessageResults[i].id), + ); + } + + return sortedChatMessageInfoItems.filter(Boolean); + }, [chatMessageInfos, rawMessageResults, threadInfo]); const measureCallback = React.useCallback( (listDataWithHeights: $ReadOnlyArray) => { diff --git a/native/chat/reaction-message-utils.js b/native/chat/reaction-message-utils.js --- a/native/chat/reaction-message-utils.js +++ b/native/chat/reaction-message-utils.js @@ -115,15 +115,18 @@ +margin: ?number, }; +type WritableContainerStyle = { + position: 'absolute', + left?: number, + right?: number, + bottom?: number, + top?: number, + ... +}; +type ContainerStyle = $ReadOnly; + type ReactionSelectionPopoverPosition = { - +containerStyle: { - +position: 'absolute', - +left?: number, - +right?: number, - +bottom?: number, - +top?: number, - ... - }, + +containerStyle: ContainerStyle, +popoverLocation: 'above' | 'below', }; function useReactionSelectionPopoverPosition({ @@ -158,9 +161,9 @@ const containerStyle = React.useMemo(() => { const { x, width, height } = initialCoordinates; - const style = {}; - - style.position = 'absolute'; + const style: WritableContainerStyle = { + position: 'absolute', + }; const extraLeftSpace = x; const extraRightSpace = windowWidth - width - x; diff --git a/native/chat/robotext-message.react.js b/native/chat/robotext-message.react.js --- a/native/chat/robotext-message.react.js +++ b/native/chat/robotext-message.react.js @@ -196,7 +196,7 @@ const contentAndHeaderOpacity = useContentAndHeaderOpacity(item); - const viewStyle = {}; + const viewStyle: { height?: number } = {}; if (!__DEV__) { // We don't force view height in dev mode because we // want to measure it in Message to see if it's correct diff --git a/native/chat/settings/thread-settings-description.react.js b/native/chat/settings/thread-settings-description.react.js --- a/native/chat/settings/thread-settings-description.react.js +++ b/native/chat/settings/thread-settings-description.react.js @@ -116,7 +116,7 @@ this.props.descriptionEditValue !== null && this.props.descriptionEditValue !== undefined ) { - const textInputStyle = {}; + const textInputStyle: { height?: number } = {}; if ( this.props.descriptionTextHeight !== undefined && this.props.descriptionTextHeight !== null diff --git a/native/chat/settings/thread-settings-push-notifs.react.js b/native/chat/settings/thread-settings-push-notifs.react.js --- a/native/chat/settings/thread-settings-push-notifs.react.js +++ b/native/chat/settings/thread-settings-push-notifs.react.js @@ -81,7 +81,7 @@ render() { const componentLabel = 'Push notifs'; - let notificationsSettingsLinkingIcon = undefined; + let notificationsSettingsLinkingIcon: React.Node = undefined; if (!this.props.hasPushPermissions) { notificationsSettingsLinkingIcon = ( ); } - const snakes = []; + const snakes: Array = []; if (triggerReply) { snakes.push(replySwipeSnake); } diff --git a/native/components/feature-flags-provider.react.js b/native/components/feature-flags-provider.react.js --- a/native/components/feature-flags-provider.react.js +++ b/native/components/feature-flags-provider.react.js @@ -71,7 +71,7 @@ 5000, ); - const configuration = {}; + const configuration: { [string]: true } = {}; for (const feature of config.enabledFeatures) { configuration[feature] = true; } diff --git a/native/components/node-height-measurer.react.js b/native/components/node-height-measurer.react.js --- a/native/components/node-height-measurer.react.js +++ b/native/components/node-height-measurer.react.js @@ -45,9 +45,9 @@ +initialMeasuredHeights?: ?$ReadOnlyMap, ... }; -type State = { +type WritableState = { // These are the dummies currently being rendered - +currentlyMeasuring: $ReadOnlyArray<{ + currentlyMeasuring: $ReadOnlyArray<{ +measureKey: string, +dummy: React.Element, }>, @@ -55,16 +55,17 @@ // avoid considering any onLayouts that got queued before we issued the // remeasure, we increment the "iteration" and only count onLayouts with the // right value - +iteration: number, + iteration: number, // We cache the measured heights here, keyed by measure key - +measuredHeights: Map, + measuredHeights: Map, // We cache the results of calling mergeItemWithHeight on measured items after // measuring their height, keyed by ID - +measurableItems: Map>, + measurableItems: Map>, // We cache the results of calling mergeItemWithHeight on items that aren't // measurable (eg. itemToKey reurns falsey), keyed by ID - +unmeasurableItems: Map>, + unmeasurableItems: Map>, }; +type State = $ReadOnly>; class NodeHeightMeasurer extends React.PureComponent< Props, State, @@ -434,7 +435,7 @@ } } - const stateUpdate = {}; + const stateUpdate: Partial> = {}; if (incrementIteration) { stateUpdate.iteration = this.state.iteration + 1; } diff --git a/native/components/thread-ancestors-label.react.js b/native/components/thread-ancestors-label.react.js --- a/native/components/thread-ancestors-label.react.js +++ b/native/components/thread-ancestors-label.react.js @@ -34,7 +34,7 @@ ); const ancestorPath = React.useMemo(() => { - const path = []; + const path: Array = []; for (const thread of resolvedAncestorThreads) { path.push({thread.uiName}); path.push( diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js --- a/native/input/input-state-container.react.js +++ b/native/input/input-state-container.react.js @@ -106,6 +106,7 @@ InputStateContext, type PendingMultimediaUploads, type MultimediaProcessingStep, + type MessagePendingUploads, } from './input-state.js'; import { encryptMedia } from '../media/encryption-utils.js'; import { disposeTempFile } from '../media/file-utils.js'; @@ -123,7 +124,10 @@ +selection: NativeMediaSelection, +ids: MediaIDs, }; -type CompletedUploads = { +[localMessageID: string]: ?Set }; +type WritableCompletedUploads = { + [localMessageID: string]: ?$ReadOnlySet, +}; +type CompletedUploads = $ReadOnly; type BaseProps = { +children: React.Node, @@ -182,7 +186,7 @@ pendingSidebarCreationMessageLocalIDs = new Set(); static getCompletedUploads(props: Props, state: State): CompletedUploads { - const completedUploads = {}; + const completedUploads: WritableCompletedUploads = {}; for (const localMessageID in state.pendingUploads) { const messagePendingUploads = state.pendingUploads[localMessageID]; const rawMessageInfo = props.messageStoreMessages[localMessageID]; @@ -228,7 +232,7 @@ prevState, ); - const newPendingUploads = {}; + const newPendingUploads: PendingMultimediaUploads = {}; let pendingUploadsChanged = false; const readyMessageIDs = []; for (const localMessageID in this.state.pendingUploads) { @@ -255,7 +259,7 @@ continue; } - const newUploads = {}; + const newUploads: MessagePendingUploads = {}; let uploadsChanged = false; for (const localUploadID in messagePendingUploads) { if (!completedUploadIDs.has(localUploadID)) { @@ -618,7 +622,7 @@ } const uploadFileInputs = [], - media = []; + media: Array = []; for (const selection of selections) { const localMediaID = getNextLocalUploadID(); let ids; @@ -656,7 +660,7 @@ uploadFileInputs.push({ selection, ids }); } - const pendingUploads = {}; + const pendingUploads: MessagePendingUploads = {}; for (const uploadFileInput of uploadFileInputs) { const { localMediaID } = uploadFileInput.ids; pendingUploads[localMediaID] = { @@ -730,11 +734,11 @@ const { localMediaID } = ids; const start = selection.sendTime; const steps: Array = [selection]; - let encryptionSteps = []; + let encryptionSteps: $ReadOnlyArray = []; let serverID; let userTime; let errorMessage; - let reportPromise; + let reportPromise: ?Promise<$ReadOnlyArray>; const filesToDispose = []; const onUploadFinished = async (result: MediaMissionResult) => { @@ -1194,7 +1198,7 @@ 'InputStateContainer.uploadBlob sent incorrect input', ); - const parameters = {}; + const parameters: { [key: string]: mixed } = {}; parameters.cookie = cookie; parameters.filename = name; diff --git a/native/media/blob-utils.js b/native/media/blob-utils.js --- a/native/media/blob-utils.js +++ b/native/media/blob-utils.js @@ -118,7 +118,7 @@ invariant(firstComma > 4, 'malformed data-URI'); const base64String = dataURI.substring(firstComma + 1); - let mime = blob.type; + let mime: ?string = blob.type; if (!mime) { let mimeCheckExceptionMessage; const mimeCheckStart = Date.now(); diff --git a/native/media/ffmpeg.js b/native/media/ffmpeg.js --- a/native/media/ffmpeg.js +++ b/native/media/ffmpeg.js @@ -46,7 +46,7 @@ } possiblyRunCommands() { - let openSlots = {}; + let openSlots: { [string]: number } = {}; for (const type in this.currentCalls) { const currentCalls = this.currentCalls[type]; const maxCalls = maxSimultaneousCalls[type]; diff --git a/native/navigation/navigation-utils.js b/native/navigation/navigation-utils.js --- a/native/navigation/navigation-utils.js +++ b/native/navigation/navigation-utils.js @@ -101,7 +101,7 @@ state: State, filterFunc: (route: Route) => 'keep' | 'remove' | 'break', ): State { - const newRoutes = []; + const newRoutes: Array = []; let newIndex = state.index; let screenRemoved = false; let breakActivated = false; diff --git a/native/profile/appearance-preferences.react.js b/native/profile/appearance-preferences.react.js --- a/native/profile/appearance-preferences.react.js +++ b/native/profile/appearance-preferences.react.js @@ -96,7 +96,7 @@ render() { const { panelIosHighlightUnderlay: underlay } = this.props.colors; - const options = []; + const options: Array = []; for (let i = 0; i < optionTexts.length; i++) { const { themePreference, text } = optionTexts[i]; const icon = diff --git a/native/profile/dev-tools.react.js b/native/profile/dev-tools.react.js --- a/native/profile/dev-tools.react.js +++ b/native/profile/dev-tools.react.js @@ -105,7 +105,7 @@ render() { const { panelIosHighlightUnderlay: underlay } = this.props.colors; - const serverButtons = []; + const serverButtons: Array = []; for (const server of nodeServerOptions) { const icon = server === this.props.urlPrefix ? : null; serverButtons.push( diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js --- a/native/push/push-handler.react.js +++ b/native/push/push-handler.react.js @@ -249,7 +249,7 @@ } else { // We do this in case there was a crash, so we can clear deviceToken from // any other cookies it might be set for - const deviceTokensMap = {}; + const deviceTokensMap: { [string]: string } = {}; for (const keyserverID in this.props.deviceTokens) { const deviceToken = this.props.deviceTokens[keyserverID]; if (deviceToken) { @@ -456,7 +456,7 @@ if (deviceType === 'ios') { iosPushPermissionResponseReceived(); } - const deviceTokensMap = {}; + const deviceTokensMap: { [string]: ?string } = {}; for (const keyserverID in this.props.deviceTokens) { const keyserverDeviceToken = this.props.deviceTokens[keyserverID]; if (deviceToken !== keyserverDeviceToken) { diff --git a/native/redux/dimensions-updater.react.js b/native/redux/dimensions-updater.react.js --- a/native/redux/dimensions-updater.react.js +++ b/native/redux/dimensions-updater.react.js @@ -86,7 +86,8 @@ if (keyboardShowing) { return; } - let updates = dimensionsUpdateFromMetrics({ frame, insets }); + let updates: Partial<$ReadOnly<{ ...DimensionsInfo }>> = + dimensionsUpdateFromMetrics({ frame, insets }); if (updates.height && updates.width && updates.height !== updates.width) { updates = { ...updates, diff --git a/native/redux/edit-thread-permission-migration.js b/native/redux/edit-thread-permission-migration.js --- a/native/redux/edit-thread-permission-migration.js +++ b/native/redux/edit-thread-permission-migration.js @@ -61,7 +61,7 @@ function migrateThreadStoreForEditThreadPermissions(threadInfos: { +[id: string]: RawThreadInfo, }): RawThreadInfos { - const newThreadInfos = {}; + const newThreadInfos: { [string]: RawThreadInfo } = {}; for (const threadID in threadInfos) { const threadInfo: RawThreadInfo = threadInfos[threadID]; const updatedMembers = threadInfo.members.map(member => @@ -74,7 +74,7 @@ threadID, ); - const updatedRoles = {}; + const updatedRoles: { [string]: RoleInfo } = {}; for (const roleID in threadInfo.roles) { updatedRoles[roleID] = addDetailedThreadEditPermissionsToRole( threadInfo.roles[roleID], diff --git a/native/redux/manage-pins-permission-migration.js b/native/redux/manage-pins-permission-migration.js --- a/native/redux/manage-pins-permission-migration.js +++ b/native/redux/manage-pins-permission-migration.js @@ -56,7 +56,7 @@ function persistMigrationForManagePinsThreadPermission( threadInfos: ThreadStoreThreadInfos, ): ThreadStoreThreadInfos { - const newThreadInfos = {}; + const newThreadInfos: { [string]: RawThreadInfo } = {}; for (const threadID in threadInfos) { const threadInfo: RawThreadInfo = threadInfos[threadID]; const updatedMembers = threadInfo.members.map(member => @@ -69,7 +69,7 @@ threadID, ); - const updatedRoles = {}; + const updatedRoles: { [string]: RoleInfo } = {}; for (const roleID in threadInfo.roles) { updatedRoles[roleID] = addManagePinsThreadPermissionToRole( threadInfo.roles[roleID], diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -66,7 +66,10 @@ type ConnectionInfo, } from 'lib/types/socket-types.js'; import { defaultGlobalThemeInfo } from 'lib/types/theme-types.js'; -import type { ClientDBThreadInfo } from 'lib/types/thread-types.js'; +import type { + ClientDBThreadInfo, + RawThreadInfo, +} from 'lib/types/thread-types.js'; import { translateClientDBMessageInfoToRawMessageInfo, translateRawMessageInfoToClientDBMessageInfo, @@ -252,7 +255,7 @@ }, }), [19]: state => { - const threadInfos = {}; + const threadInfos: { [string]: RawThreadInfo } = {}; for (const threadID in state.threadStore.threadInfos) { const threadInfo = state.threadStore.threadInfos[threadID]; const { visibilityRules, ...rest } = threadInfo; @@ -352,7 +355,7 @@ }, }), [28]: state => { - const threadParentToChildren = {}; + const threadParentToChildren: { [string]: string[] } = {}; for (const threadID in state.threadStore.threadInfos) { const threadInfo = state.threadStore.threadInfos[threadID]; const parentThreadInfo = threadInfo.parentThreadID @@ -372,7 +375,7 @@ return state; } - const threadInfos = {}; + const threadInfos: { [string]: RawThreadInfo } = {}; const stack = [...rootIDs]; while (stack.length > 0) { const threadID = stack.shift(); @@ -884,7 +887,7 @@ keyserverStore: { keyserverInfos }, ...rest } = state; - const newKeyserverInfos = {}; + const newKeyserverInfos: { [string]: KeyserverInfo } = {}; for (const key in keyserverInfos) { newKeyserverInfos[key] = { ...keyserverInfos[key], @@ -1029,7 +1032,7 @@ }; const keyserverStoreTransform: Transform = createTransform( (state: KeyserverStore): PersistedKeyserverStore => { - const keyserverInfos = {}; + const keyserverInfos: { [string]: PersistedKeyserverInfo } = {}; for (const key in state.keyserverInfos) { const { connection, ...rest } = state.keyserverInfos[key]; keyserverInfos[key] = rest; @@ -1040,7 +1043,7 @@ }; }, (state: PersistedKeyserverStore): KeyserverStore => { - const keyserverInfos = {}; + const keyserverInfos: { [string]: KeyserverInfo } = {}; for (const key in state.keyserverInfos) { keyserverInfos[key] = { ...state.keyserverInfos[key], diff --git a/native/redux/redux-setup.js b/native/redux/redux-setup.js --- a/native/redux/redux-setup.js +++ b/native/redux/redux-setup.js @@ -67,14 +67,16 @@ isStaff(state.currentUserInfo.id))) ) { // 1. Construct set of keys expected to be REHYDRATED - const defaultKeys = Object.keys(defaultState); + const defaultKeys: $ReadOnlyArray = Object.keys(defaultState); const expectedKeys = defaultKeys.filter( each => !persistConfig.blacklist.includes(each), ); const expectedKeysSet = new Set(expectedKeys); // 2. Construct set of keys actually REHYDRATED - const rehydratedKeys = Object.keys(action.payload ?? {}); + const rehydratedKeys: $ReadOnlyArray = Object.keys( + action.payload ?? {}, + ); const rehydratedKeysSet = new Set(rehydratedKeys); // 3. Determine the difference between the two sets diff --git a/native/redux/remove-select-role-permissions.js b/native/redux/remove-select-role-permissions.js --- a/native/redux/remove-select-role-permissions.js +++ b/native/redux/remove-select-role-permissions.js @@ -1,6 +1,10 @@ // @flow -import type { RawThreadInfos } from 'lib/types/thread-types.js'; +import type { + RawThreadInfos, + RawThreadInfo, + RoleInfo, +} from 'lib/types/thread-types.js'; import { permissionsToRemoveInMigration } from 'lib/utils/migration-utils.js'; function persistMigrationToRemoveSelectRolePermissions( @@ -13,16 +17,16 @@ return {}; } - const updatedThreadInfos = {}; + const updatedThreadInfos: { [string]: RawThreadInfo } = {}; for (const threadID in rawThreadInfos) { const threadInfo = rawThreadInfos[threadID]; const { roles } = threadInfo; - const updatedRoles = {}; + const updatedRoles: { [string]: RoleInfo } = {}; for (const roleID in roles) { const role = roles[roleID]; const { permissions: rolePermissions } = role; - const updatedPermissions = {}; + const updatedPermissions: { [string]: boolean } = {}; for (const permission in rolePermissions) { if (!permissionsToRemoveInMigration.includes(permission)) { updatedPermissions[permission] = rolePermissions[permission]; diff --git a/native/redux/update-roles-and-permissions.js b/native/redux/update-roles-and-permissions.js --- a/native/redux/update-roles-and-permissions.js +++ b/native/redux/update-roles-and-permissions.js @@ -22,7 +22,7 @@ function constructThreadTraversalNodes( threadStoreInfos: ThreadStoreThreadInfos, ): $ReadOnlyArray<$ReadOnly> { - const parentThreadMap = {}; + const parentThreadMap: { [string]: Array } = {}; for (const threadInfo of values(threadStoreInfos)) { const parentThreadID = threadInfo.parentThreadID ?? 'root'; @@ -79,7 +79,9 @@ const threadInfo: RawThreadInfo = updatedThreadStoreInfos[node.threadID]; const updatedMembers = []; - const memberToThreadPermissionsForChildren = {}; + const memberToThreadPermissionsForChildren: { + [string]: ?ThreadPermissionsBlob, + } = {}; for (const member: MemberInfo of threadInfo.members) { const { id, role } = member; diff --git a/native/themes/colors.js b/native/themes/colors.js --- a/native/themes/colors.js +++ b/native/themes/colors.js @@ -283,7 +283,7 @@ obj: IS, themeColors: Colors, ): StyleSheetOf { - const result = {}; + const result: Styles = {}; for (const key in obj) { const style = obj[key]; const filledInStyle = { ...style }; diff --git a/native/tooltip/tooltip.react.js b/native/tooltip/tooltip.react.js --- a/native/tooltip/tooltip.react.js +++ b/native/tooltip/tooltip.react.js @@ -368,13 +368,13 @@ ...navAndRouteForFlow } = this.props; - const tooltipContainerStyle = [styles.itemContainer]; + const tooltipContainerStyle: Array = [styles.itemContainer]; if (this.tooltipLocation === 'fixed') { tooltipContainerStyle.push(styles.itemContainerFixed); } - const items = [ + const items: Array = [ , prevIndentation: ?number, ): $ReadOnlyArray { - let results = []; + let results: Array = []; for (const item of data) { const isOpen = expanded.includes(item.threadInfo.id);