diff --git a/lib/actions/upload-actions.js b/lib/actions/upload-actions.js --- a/lib/actions/upload-actions.js +++ b/lib/actions/upload-actions.js @@ -46,7 +46,7 @@ const abortHandler = callbacks && callbacks.abortHandler; const uploadBlob = callbacks && callbacks.uploadBlob; - const stringExtras = {}; + const stringExtras: { [string]: string } = {}; if (extras.height !== null && extras.height !== undefined) { stringExtras.height = extras.height.toString(); } @@ -71,8 +71,8 @@ const response = await callServerEndpoint( 'upload_multimedia', { - multimedia: [multimedia], ...stringExtras, + multimedia: [multimedia], }, { onProgress, diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js --- a/lib/actions/user-actions.js +++ b/lib/actions/user-actions.js @@ -182,7 +182,7 @@ }; function mergeUserInfos(...userInfoArrays: UserInfo[][]): UserInfo[] { - const merged = {}; + const merged: { [string]: UserInfo } = {}; for (const userInfoArray of userInfoArrays) { for (const userInfo of userInfoArray) { merged[userInfo.id] = userInfo; diff --git a/lib/components/chat-mention-provider.react.js b/lib/components/chat-mention-provider.react.js --- a/lib/components/chat-mention-provider.react.js +++ b/lib/components/chat-mention-provider.react.js @@ -81,9 +81,13 @@ chatMentionCandidatesObj: ChatMentionCandidatesObj, communityThreadIDForGenesisThreads: { +[id: string]: string }, } { - const result = {}; - const visitedGenesisThreads = new Set(); - const communityThreadIDForGenesisThreads = {}; + const result: { + [string]: { + [string]: ResolvedThreadInfo | MinimallyEncodedResolvedThreadInfo, + }, + } = {}; + const visitedGenesisThreads = new Set(); + const communityThreadIDForGenesisThreads: { [string]: string } = {}; for (const currentThreadID in threadInfos) { const currentThreadInfo = threadInfos[currentThreadID]; const { community: currentThreadCommunity } = currentThreadInfo; @@ -94,9 +98,9 @@ continue; } if (!result[currentThreadCommunity]) { - result[currentThreadCommunity] = { - [currentThreadCommunity]: threadInfos[currentThreadCommunity], - }; + result[currentThreadCommunity] = {}; + result[currentThreadCommunity][currentThreadCommunity] = + threadInfos[currentThreadCommunity]; } // Handle GENESIS community case: mentioning inside GENESIS should only // show chats and threads inside the top level that is below GENESIS. @@ -214,7 +218,7 @@ +[id: string]: SentencePrefixSearchIndex, } { return React.useMemo(() => { - const result = {}; + const result: { [string]: SentencePrefixSearchIndex } = {}; for (const communityThreadID in chatMentionCandidatesObj) { const searchIndex = new SentencePrefixSearchIndex(); const searchIndexEntries = []; diff --git a/lib/permissions/thread-permissions.js b/lib/permissions/thread-permissions.js --- a/lib/permissions/thread-permissions.js +++ b/lib/permissions/thread-permissions.js @@ -44,19 +44,24 @@ permissions: ?ThreadPermissionsBlob, threadID: string, ): ThreadPermissionsInfo { - const result = {}; + const result: { [permission: ThreadPermission]: ThreadPermissionInfo } = {}; for (const permissionName in threadPermissions) { const permissionKey = threadPermissions[permissionName]; const permission = permissionLookup(permissions, permissionKey); - let source = null; + let entry: ThreadPermissionInfo = { value: false, source: null }; if (permission) { - if (permissions && permissions[permissionKey]) { - source = permissions[permissionKey].source; + const blobEntry = permissions ? permissions[permissionKey] : null; + if (blobEntry) { + invariant( + blobEntry.value, + 'permissionLookup returned true but blob had false permission!', + ); + entry = { value: true, source: blobEntry.source }; } else { - source = threadID; + entry = { value: true, source: threadID }; } } - result[permissionKey] = { value: permission, source }; + result[permissionKey] = entry; } return result; } @@ -71,7 +76,7 @@ threadID: string, threadType: ThreadType, ): ?ThreadPermissionsBlob { - let permissions = {}; + let permissions: { [permission: string]: ThreadPermissionInfo } = {}; if (permissionsFromParent) { for (const permissionKey in permissionsFromParent) { @@ -143,7 +148,8 @@ if (!permissions) { return null; } - const permissionsForChildren = {}; + const permissionsForChildren: { [permission: string]: ThreadPermissionInfo } = + {}; for (const permissionKey in permissions) { const permissionValue = permissions[permissionKey]; const parsed = parseThreadPermissionString(permissionKey); diff --git a/lib/reducers/draft-reducer.js b/lib/reducers/draft-reducer.js --- a/lib/reducers/draft-reducer.js +++ b/lib/reducers/draft-reducer.js @@ -73,7 +73,7 @@ }, }; } else if (action.type === setClientDBStoreActionType) { - const drafts = {}; + const drafts: { [string]: string } = {}; for (const dbDraftInfo of action.payload.drafts) { drafts[dbDraftInfo.key] = dbDraftInfo.text; } diff --git a/lib/reducers/entry-reducer.js b/lib/reducers/entry-reducer.js --- a/lib/reducers/entry-reducer.js +++ b/lib/reducers/entry-reducer.js @@ -92,7 +92,7 @@ newEntryInfos: $ReadOnlyArray, threadInfos: RawThreadInfos, ) { - const mergedEntryInfos = {}; + const mergedEntryInfos: { [string]: RawEntryInfo } = {}; let someEntryUpdated = false; for (const rawEntryInfo of newEntryInfos) { diff --git a/lib/reducers/invite-links-reducer.js b/lib/reducers/invite-links-reducer.js --- a/lib/reducers/invite-links-reducer.js +++ b/lib/reducers/invite-links-reducer.js @@ -9,7 +9,7 @@ deleteAccountActionTypes, logOutActionTypes, } from '../actions/user-actions.js'; -import type { InviteLinksStore } from '../types/link-types.js'; +import type { InviteLinksStore, CommunityLinks } from '../types/link-types.js'; import type { BaseAction } from '../types/redux-types.js'; import { setNewSessionActionType } from '../utils/action-utils.js'; @@ -18,7 +18,7 @@ action: BaseAction, ): InviteLinksStore { if (action.type === fetchPrimaryInviteLinkActionTypes.success) { - const links = {}; + const links: { [string]: CommunityLinks } = {}; for (const link of action.payload.links) { links[link.communityID] = { ...state.links[link.communityID], diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js --- a/lib/reducers/message-reducer.js +++ b/lib/reducers/message-reducer.js @@ -218,7 +218,7 @@ pendingToRealizedThreadIDsSelector(threadInfos); const messageStoreOperations: MessageStoreOperation[] = []; - const messages = {}; + const messages: { [string]: RawMessageInfo } = {}; for (const storeMessageID in messageStore.messages) { const message = messageStore.messages[storeMessageID]; const newThreadID = pendingToRealizedThreadIDs.get(message.threadID); @@ -243,9 +243,9 @@ messageStoreOperations.push(updateMsgOperation); } - const threads = {}; + const threads: { [string]: ThreadMessageInfo } = {}; const reassignedThreadIDs = []; - const updatedThreads = {}; + const updatedThreads: { [string]: ThreadMessageInfo } = {}; const threadsToRemove = []; for (const threadID in messageStore.threads) { const threadMessageInfo = messageStore.threads[threadID]; @@ -304,7 +304,7 @@ function mergeNewMessages( oldMessageStore: MessageStore, newMessageInfos: $ReadOnlyArray, - truncationStatus: { [threadID: string]: MessageTruncationStatus }, + truncationStatus: { +[threadID: string]: MessageTruncationStatus }, threadInfos: RawThreadInfos, ): MergeNewMessagesResult { const { @@ -455,8 +455,8 @@ ); const oldMessageInfosToCombine = []; const threadsThatNeedMessageIDsResorted = []; - const local = {}; - const updatedThreads = {}; + const local: { [string]: LocalMessageInfo } = {}; + const updatedThreads: { [string]: ThreadMessageInfo } = {}; const threads = _flow( _mapValuesWithKeys((messageIDs: string[], threadID: string) => { const oldThread = updatedMessageStore.threads[threadID]; @@ -640,7 +640,7 @@ messageStoreOperations.push(...reassignMessagesOps); const watchedIDs = [...threadWatcher.getWatchedIDs(), ...reassignedThreadIDs]; - const filteredThreads = {}; + const filteredThreads: { [string]: ThreadMessageInfo } = {}; const threadsToRemoveMessagesFrom = []; const messageIDsToRemove = []; for (const threadID in reassignedMessageStore.threads) { @@ -654,7 +654,7 @@ } } - const updatedThreads = {}; + const updatedThreads: { [string]: ThreadMessageInfo } = {}; for (const threadID in threadInfos) { const threadInfo = threadInfos[threadID]; if ( @@ -866,7 +866,7 @@ newThreadInfos, ); } else if (action.type === registerActionTypes.success) { - const truncationStatuses = {}; + const truncationStatuses: { [string]: MessageTruncationStatus } = {}; for (const messageInfo of action.payload.rawMessageInfos) { truncationStatuses[messageInfo.threadID] = messageTruncationStatus.EXHAUSTIVE; @@ -915,7 +915,7 @@ ); } else if (action.type === sendEditMessageActionTypes.success) { const { newMessageInfos } = action.payload; - const truncationStatuses = {}; + const truncationStatuses: { [string]: MessageTruncationStatus } = {}; for (const messageInfo of newMessageInfos) { truncationStatuses[messageInfo.threadID] = messageTruncationStatus.UNCHANGED; @@ -1142,7 +1142,7 @@ }, }; } else if (action.type === saveMessagesActionType) { - const truncationStatuses = {}; + const truncationStatuses: { [string]: MessageTruncationStatus } = {}; for (const messageInfo of action.payload.rawMessageInfos) { truncationStatuses[messageInfo.threadID] = messageTruncationStatus.UNCHANGED; @@ -1169,7 +1169,7 @@ const now = Date.now(); const messageIDsToPrune = []; - const updatedThreads = {}; + const updatedThreads: { [string]: ThreadMessageInfo } = {}; for (const threadID of action.payload.threadIDs) { let thread = messageStore.threads[threadID]; if (!thread) { @@ -1541,7 +1541,7 @@ // When starting the app on native, we filter out any local-only multimedia // messages because the relevant context is no longer available const messageIDsToBeRemoved = []; - const threadsToAdd = {}; + const threadsToAdd: { [string]: ThreadMessageInfo } = {}; for (const id in actionPayloadMessages) { const message = actionPayloadMessages[id]; const { threadID } = message; diff --git a/lib/reducers/thread-reducer.js b/lib/reducers/thread-reducer.js --- a/lib/reducers/thread-reducer.js +++ b/lib/reducers/thread-reducer.js @@ -41,7 +41,11 @@ fullStateSyncActionType, incrementalStateSyncActionType, } from '../types/socket-types.js'; -import type { RawThreadInfos, ThreadStore } from '../types/thread-types.js'; +import type { + RawThreadInfo, + RawThreadInfos, + ThreadStore, +} from '../types/thread-types.js'; import { type ClientUpdateInfo, processUpdatesActionType, @@ -293,7 +297,7 @@ threadStoreOperations, }; } else if (action.type === updateActivityActionTypes.success) { - const updatedThreadInfos = {}; + const updatedThreadInfos: { [string]: RawThreadInfo } = {}; for (const setToUnread of action.payload.result.unfocusedToUnread) { const threadInfo = state.threadInfos[setToUnread]; if (threadInfo && !threadInfo.currentUser.unread) { diff --git a/lib/selectors/chat-selectors.js b/lib/selectors/chat-selectors.js --- a/lib/selectors/chat-selectors.js +++ b/lib/selectors/chat-selectors.js @@ -481,7 +481,7 @@ ); const renderedReactions: ReactionInfo = (() => { - const result = {}; + const result: { [string]: MessageReactionInfo } = {}; let messageReactsMap; if (originalMessageInfo.id) { diff --git a/lib/selectors/invite-links-selectors.js b/lib/selectors/invite-links-selectors.js --- a/lib/selectors/invite-links-selectors.js +++ b/lib/selectors/invite-links-selectors.js @@ -10,7 +10,7 @@ } = createSelector( (state: AppState) => state.inviteLinksStore.links, (links: InviteLinks) => { - const primaryLinks = {}; + const primaryLinks: { [string]: InviteLink } = {}; for (const communityID in links) { const communityLinks = links[communityID]; if (communityLinks.primaryLink) { diff --git a/lib/selectors/socket-selectors.js b/lib/selectors/socket-selectors.js --- a/lib/selectors/socket-selectors.js +++ b/lib/selectors/socket-selectors.js @@ -108,7 +108,7 @@ } else if (serverRequest.type === serverRequestTypes.CHECK_STATE) { const query = calendarQuery(calendarActive); - const hashResults = {}; + const hashResults: { [string]: boolean } = {}; for (const key in serverRequest.hashesToCheck) { const expectedHashValue = serverRequest.hashesToCheck[key]; let hashValue; diff --git a/lib/selectors/thread-selectors.js b/lib/selectors/thread-selectors.js --- a/lib/selectors/thread-selectors.js +++ b/lib/selectors/thread-selectors.js @@ -161,7 +161,7 @@ onScreen: $ReadOnlyArray, includeDeleted: boolean, ) => { - const allDaysWithinRange = {}, + const allDaysWithinRange: { [string]: string[] } = {}, startDate = dateFromString(startDateString), endDate = dateFromString(endDateString); for ( @@ -191,7 +191,7 @@ } = createSelector( threadInfoSelector, (threadInfos: { +[id: string]: ThreadInfo }) => { - const result = {}; + const result: { [string]: ThreadInfo[] } = {}; for (const id in threadInfos) { const threadInfo = threadInfos[id]; const parentThreadID = threadInfo.parentThreadID; @@ -199,7 +199,7 @@ continue; } if (result[parentThreadID] === undefined) { - result[parentThreadID] = []; + result[parentThreadID] = ([]: ThreadInfo[]); } result[parentThreadID].push(threadInfo); } @@ -212,7 +212,7 @@ } = createSelector( threadInfoSelector, (threadInfos: { +[id: string]: ThreadInfo }) => { - const result = {}; + const result: { [string]: ThreadInfo[] } = {}; for (const id in threadInfos) { const threadInfo = threadInfos[id]; const { containingThreadID } = threadInfo; @@ -220,7 +220,7 @@ continue; } if (result[containingThreadID] === undefined) { - result[containingThreadID] = []; + result[containingThreadID] = ([]: ThreadInfo[]); } result[containingThreadID].push(threadInfo); } @@ -405,7 +405,7 @@ ) => { const pendingToRealizedThreadIDs = pendingToRealizedThreadIDsSelector(rawThreadInfos); - const result = {}; + const result: { [string]: ThreadInfo } = {}; for (const realizedID of pendingToRealizedThreadIDs.values()) { const threadInfo = threadInfos[realizedID]; if (threadInfo && threadInfo.sourceMessageID) { diff --git a/lib/shared/entry-utils.js b/lib/shared/entry-utils.js --- a/lib/shared/entry-utils.js +++ b/lib/shared/entry-utils.js @@ -102,7 +102,7 @@ calendarQuery: CalendarQuery, ): { +[id: string]: RawEntryInfo } { let filtered = false; - const filteredRawEntryInfos = {}; + const filteredRawEntryInfos: { [string]: RawEntryInfo } = {}; for (const id in rawEntryInfos) { const rawEntryInfo = rawEntryInfos[id]; if (!rawEntryInfoWithinCalendarQuery(rawEntryInfo, calendarQuery)) { @@ -228,7 +228,7 @@ function serverEntryInfosObject( array: $ReadOnlyArray, ): RawEntryInfos { - const obj = {}; + const obj: { [string]: RawEntryInfo } = {}; for (const rawEntryInfo of array) { const entryInfo = serverEntryInfo(rawEntryInfo); if (!entryInfo) { diff --git a/lib/shared/messages/add-members-message-spec.js b/lib/shared/messages/add-members-message-spec.js --- a/lib/shared/messages/add-members-message-spec.js +++ b/lib/shared/messages/add-members-message-spec.js @@ -118,7 +118,7 @@ threadInfo: ThreadInfo, params: NotificationTextsParams, ): Promise { - const addedMembersObject = {}; + const addedMembersObject: { [string]: RelativeUserInfo } = {}; for (const messageInfo of messageInfos) { invariant( messageInfo.type === messageTypes.ADD_MEMBERS, diff --git a/lib/shared/messages/change-role-message-spec.js b/lib/shared/messages/change-role-message-spec.js --- a/lib/shared/messages/change-role-message-spec.js +++ b/lib/shared/messages/change-role-message-spec.js @@ -152,7 +152,7 @@ threadInfo: ThreadInfo, params: NotificationTextsParams, ): Promise { - const membersObject = {}; + const membersObject: { [string]: RelativeUserInfo } = {}; for (const messageInfo of messageInfos) { invariant( messageInfo.type === messageTypes.CHANGE_ROLE, diff --git a/lib/shared/messages/join-thread-message-spec.js b/lib/shared/messages/join-thread-message-spec.js --- a/lib/shared/messages/join-thread-message-spec.js +++ b/lib/shared/messages/join-thread-message-spec.js @@ -91,7 +91,7 @@ messageInfos: $ReadOnlyArray, threadInfo: ThreadInfo, ): Promise { - const joinerArray = {}; + const joinerArray: { [string]: RelativeUserInfo } = {}; for (const messageInfo of messageInfos) { invariant( messageInfo.type === messageTypes.JOIN_THREAD, diff --git a/lib/shared/messages/leave-thread-message-spec.js b/lib/shared/messages/leave-thread-message-spec.js --- a/lib/shared/messages/leave-thread-message-spec.js +++ b/lib/shared/messages/leave-thread-message-spec.js @@ -91,7 +91,7 @@ messageInfos: $ReadOnlyArray, threadInfo: ThreadInfo, ): Promise { - const leaverBeavers = {}; + const leaverBeavers: { [string]: RelativeUserInfo } = {}; for (const messageInfo of messageInfos) { invariant( messageInfo.type === messageTypes.LEAVE_THREAD, diff --git a/lib/shared/messages/remove-members-message-spec.js b/lib/shared/messages/remove-members-message-spec.js --- a/lib/shared/messages/remove-members-message-spec.js +++ b/lib/shared/messages/remove-members-message-spec.js @@ -118,7 +118,7 @@ threadInfo: ThreadInfo, params: NotificationTextsParams, ): Promise { - const removedMembersObject = {}; + const removedMembersObject: { [string]: RelativeUserInfo } = {}; for (const messageInfo of messageInfos) { invariant( messageInfo.type === messageTypes.REMOVE_MEMBERS, diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js --- a/lib/shared/thread-utils.js +++ b/lib/shared/thread-utils.js @@ -483,7 +483,7 @@ pinnedCount: 0, }; - const userInfos = {}; + const userInfos: { [string]: UserInfo } = {}; for (const member of members) { const { id, username } = member; userInfos[id] = { id, username }; @@ -1791,7 +1791,7 @@ threadInfo: ThreadInfo | MinimallyEncodedThreadInfo, ): RoleAndMemberCount { return React.useMemo(() => { - const roleIDsToNames = {}; + const roleIDsToNames: { [string]: string } = {}; Object.keys(threadInfo.roles).forEach(roleID => { roleIDsToNames[roleID] = threadInfo.roles[roleID].name; @@ -1828,7 +1828,8 @@ threadInfo: ThreadInfo, ): RoleUserSurfacedPermissions { return React.useMemo(() => { - const roleNamesToPermissions = {}; + const roleNamesToPermissions: { [string]: Set } = + {}; Object.keys(threadInfo.roles).forEach(roleID => { const roleName = threadInfo.roles[roleID].name; diff --git a/lib/socket/socket.react.js b/lib/socket/socket.react.js --- a/lib/socket/socket.react.js +++ b/lib/socket/socket.react.js @@ -164,7 +164,7 @@ }); const socket = this.props.openSocket(); - const openObject = {}; + const openObject: { initializeMessageSent?: true } = {}; socket.onopen = () => { if (this.socket === socket) { this.initializeSocket(); @@ -552,7 +552,6 @@ 'inflightRequests falsey inside sendInitialMessage', ); const messageID = this.nextClientMessageID++; - const promises = {}; const shouldSendInitialPlatformDetails = !_isEqual( this.props.lastCommunicatedPlatformDetails, @@ -566,13 +565,14 @@ }); } + let activityUpdatePromise; const { queuedActivityUpdates } = this.props.connection; if (queuedActivityUpdates.length > 0) { clientResponses.push({ type: serverRequestTypes.INITIAL_ACTIVITY_UPDATES, activityUpdates: queuedActivityUpdates, }); - promises.activityUpdateMessage = inflightRequests.fetchResponse( + activityUpdatePromise = inflightRequests.fetchResponse( messageID, serverSocketMessageTypes.ACTIVITY_UPDATE_RESPONSE, ); @@ -592,14 +592,17 @@ this.initializedWithUserState = this.props.preRequestUserState; this.sendMessage(initialMessage); - promises.stateSyncMessage = inflightRequests.fetchResponse( + const stateSyncPromise = inflightRequests.fetchResponse( messageID, serverSocketMessageTypes.STATE_SYNC, ); - const { stateSyncMessage, activityUpdateMessage } = await promiseAll( - promises, - ); + // https://flow.org/try/#1N4Igxg9gdgZglgcxALlAJwKYEMwBcD6aArlLnALYYrgA2WAzvXGCADQgYAeOBARgJ74AJhhhYiNXClzEM7DFCLl602QF92kEdQb8oYAAQwSeONAMAHNBHJx6GAII0aAHgAqyA8AMBqANoA1hj8nvQycFAIALqetpwYQgZqAHwAFAA6UAYGERZEuJ4AJABK2EIA8lA0-O7JrJkAlJ4ACta29i6F5bwAVgCyWBburAa4-BYYEDAGhVgA7lhwuMnJXpnZkFBhlm12GPQGALwGflEA3OsGm9tB-AfH3T0YeAB0t-SpufkNF1lGEGgDKkaBhcDkjgYAAxncEuAzvF4gyK4AAWMLgPh8DTWfw20BuwQh7z8cHOlzxWzBVhsewhX1wgWCZNxOxp9noLzy9BRqWp7QwP0uaku1zBmHoElw9wM80WYNabIwLywzl5u3Zgr+ooMAgAclhKJ5gH4wmgItFYnB4kI1BDgGpftkYACgSCwXAIdDYfDghykQhUejMdjgOSrviwbcib6Sczstk9QaMIz+FEIeLJfRY46kpdMLgiGgsonKL9hVBMrp9EYTGRzPYoEIAJJQJZwFV9fb0LAIDCpEOXN2jfa4BX8nNwaYZEAojDOCDpEAvMJYNBSgDqSx5i4Ci4aA5ZuBHY9pxxP9he4ogNAAbn2ZEQBTny5dZUtWfynDRUt4j2FzxgSSamobAgHeaBMNA1A3pCLwAEwAIwACwvJCIBqEAA + // $FlowFixMe fixed in Flow 0.214 + const { stateSyncMessage, activityUpdateMessage } = await promiseAll({ + activityUpdateMessage: activityUpdatePromise, + stateSyncMessage: stateSyncPromise, + }); if (shouldSendInitialPlatformDetails) { this.props.dispatch({ diff --git a/lib/utils/conversion-utils.js b/lib/utils/conversion-utils.js --- a/lib/utils/conversion-utils.js +++ b/lib/utils/conversion-utils.js @@ -88,7 +88,7 @@ } if (validator.meta.kind === 'interface' && typeof input === 'object') { const recastValidator: TInterface = (validator: any); - const result = {}; + const result: { [string]: mixed } = {}; for (const key in input) { const innerValidator = recastValidator.meta.props[key]; result[key] = convertObject( diff --git a/lib/utils/cookie-utils.js b/lib/utils/cookie-utils.js --- a/lib/utils/cookie-utils.js +++ b/lib/utils/cookie-utils.js @@ -3,7 +3,7 @@ function parseCookies(header: string): { +[string]: string } { const values = header.split(';').map(v => v.split('=')); - const cookies = {}; + const cookies: { [string]: string } = {}; for (const [key, value] of values) { cookies[decodeURIComponent(key.trim())] = decodeURIComponent(value.trim()); } diff --git a/lib/utils/entity-helpers.js b/lib/utils/entity-helpers.js --- a/lib/utils/entity-helpers.js +++ b/lib/utils/entity-helpers.js @@ -103,7 +103,9 @@ options, ); return React.useMemo(() => { - const obj = {}; + const obj: { + [string]: ResolvedThreadInfo | MinimallyEncodedResolvedThreadInfo, + } = {}; for (const resolvedThreadInfo of resolvedThreadInfosArray) { obj[resolvedThreadInfo.id] = resolvedThreadInfo; } diff --git a/lib/utils/promises.js b/lib/utils/promises.js --- a/lib/utils/promises.js +++ b/lib/utils/promises.js @@ -2,7 +2,7 @@ type Promisable = Promise | T; -async function promiseAll }>( +async function promiseAll }>( input: T, ): Promise<$ObjMap> { const promises = []; @@ -13,7 +13,7 @@ promises.push(promise); } const results = await Promise.all(promises); - const byName = {}; + const byName: { [string]: mixed } = {}; for (let i = 0; i < keys.length; i++) { const key = keys[i]; byName[key] = results[i]; diff --git a/lib/utils/url-utils.js b/lib/utils/url-utils.js --- a/lib/utils/url-utils.js +++ b/lib/utils/url-utils.js @@ -9,21 +9,23 @@ pendingThreadIDRegex, } from './validation-utils.js'; -export type URLInfo = { - +year?: number, - +month?: number, // 1-indexed - +verify?: string, - +calendar?: boolean, - +chat?: boolean, - +thread?: string, - +settings?: 'account' | 'keyservers' | 'danger-zone', - +threadCreation?: boolean, - +selectedUserList?: $ReadOnlyArray, - +inviteSecret?: string, - +qrCode?: boolean, +type MutableURLInfo = { + year?: number, + month?: number, // 1-indexed + verify?: string, + calendar?: boolean, + chat?: boolean, + thread?: string, + settings?: 'account' | 'keyservers' | 'danger-zone', + threadCreation?: boolean, + selectedUserList?: $ReadOnlyArray, + inviteSecret?: string, + qrCode?: boolean, ... }; +export type URLInfo = $ReadOnly; + export const urlInfoValidator: TInterface = tShape({ year: t.maybe(t.Number), month: t.maybe(t.Number), @@ -78,7 +80,7 @@ const inviteLinkMatches = inviteLinkRegex.exec(url); const qrCodeLoginMatches = qrCodeLoginRegex.exec(url); - const returnObj = {}; + const returnObj: MutableURLInfo = {}; if (yearMatches) { returnObj.year = parseInt(yearMatches[2], 10); }