[Dev] Fix action typings (#2813)

This commit is contained in:
Alexander Zinchuk 2023-03-19 22:30:56 -05:00
parent 2188aa26ce
commit 4151a25954
7 changed files with 95 additions and 93 deletions

View File

@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../../global';
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import type { ApiSticker } from '../../../api/types'; import type { ApiSticker } from '../../../api/types';
import type { GlobalActions } from '../../../global/types'; import type { GlobalActions } from '../../../global';
import { COMPOSER_EMOJI_SIZE_PICKER } from '../../../config'; import { COMPOSER_EMOJI_SIZE_PICKER } from '../../../config';
import { selectIsChatWithSelf, selectIsCurrentUserPremium } from '../../../global/selectors'; import { selectIsChatWithSelf, selectIsCurrentUserPremium } from '../../../global/selectors';

View File

@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../../global';
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import type { ApiSticker, ApiVideo } from '../../../api/types'; import type { ApiSticker, ApiVideo } from '../../../api/types';
import type { GlobalActions } from '../../../global/types'; import type { GlobalActions } from '../../../global';
import { IS_TOUCH_ENV } from '../../../util/environment'; import { IS_TOUCH_ENV } from '../../../util/environment';
import { fastRaf } from '../../../util/schedulers'; import { fastRaf } from '../../../util/schedulers';

View File

@ -810,7 +810,7 @@ addActionHandler('closeMessageLanguageModal', (global, actions, payload): Action
}); });
addActionHandler('copySelectedMessages', (global, actions, payload): ActionReturnType => { addActionHandler('copySelectedMessages', (global, actions, payload): ActionReturnType => {
const { tabId = getCurrentTabId() } = payload; const { tabId = getCurrentTabId() } = payload || {};
const tabState = selectTabState(global, tabId); const tabState = selectTabState(global, tabId);
if (!tabState.selectedMessages) { if (!tabState.selectedMessages) {
return; return;

View File

@ -1,7 +1,7 @@
import type { ActionOptions } from '../lib/teact/teactn'; import type { ActionOptions } from '../lib/teact/teactn';
import { typify } from '../lib/teact/teactn'; import { typify } from '../lib/teact/teactn';
import type { import type {
GlobalState, ActionPayloads, RequiredGlobalState, RequiredActionPayloads, GlobalState, ActionPayloads, RequiredActionPayloads, RequiredGlobalState,
} from './types'; } from './types';
const typed = typify<GlobalState, ActionPayloads & RequiredActionPayloads>(); const typed = typify<GlobalState, ActionPayloads & RequiredActionPayloads>();
@ -46,3 +46,4 @@ export const addActionHandler = typed.addActionHandler as <ActionName extends Pr
handler: ActionHandlers[ActionName], handler: ActionHandlers[ActionName],
) => void; ) => void;
export const withGlobal = typed.withGlobal; export const withGlobal = typed.withGlobal;
export type GlobalActions = ReturnType<typeof getActions>;

View File

@ -1,92 +1,92 @@
import type { import type {
ApiAppConfig,
ApiAttachBot,
ApiAttachment,
ApiAvailableReaction,
ApiChannelStatistics,
ApiChat, ApiChat,
ApiChatAdminRights,
ApiChatBannedRights,
ApiChatFolder,
ApiChatReactions,
ApiChatType,
ApiConfig,
ApiContact,
ApiCountry,
ApiCountryCode,
ApiError,
ApiExportedInvite,
ApiFormattedText,
ApiGlobalMessageSearchType,
ApiGroupCall,
ApiGroupStatistics,
ApiInputInvoice,
ApiInviteInfo,
ApiInvoice,
ApiKeyboardButton,
ApiMessage, ApiMessage,
ApiMessageEntity,
ApiMessageStatistics,
ApiNewPoll,
ApiNotification,
ApiPaymentCredentials,
ApiPaymentFormNativeParams,
ApiPaymentSavedInfo,
ApiPhoneCall,
ApiPhoto,
ApiPremiumPromo,
ApiReaction,
ApiReceipt,
ApiReportReason,
ApiSendMessageAction,
ApiSession,
ApiSessionData,
ApiSponsoredMessage,
ApiSticker,
ApiStickerSet,
ApiStickerSetInfo,
ApiThemeParameters,
ApiThreadInfo, ApiThreadInfo,
ApiUser, ApiTranscription,
ApiUserStatus, ApiTypingStatus,
ApiUpdate,
ApiUpdateAuthorizationStateType, ApiUpdateAuthorizationStateType,
ApiUpdateConnectionStateType, ApiUpdateConnectionStateType,
ApiStickerSet, ApiUser,
ApiSticker, ApiUserStatus,
ApiWebPage,
ApiVideo, ApiVideo,
ApiFormattedText,
ApiChatFolder,
ApiWallpaper, ApiWallpaper,
ApiNotification, ApiWebPage,
ApiError,
ApiGlobalMessageSearchType,
ApiPaymentSavedInfo,
ApiSession,
ApiNewPoll,
ApiInviteInfo,
ApiCountryCode,
ApiCountry,
ApiGroupCall,
ApiAvailableReaction,
ApiAppConfig,
ApiSponsoredMessage,
ApiChannelStatistics,
ApiGroupStatistics,
ApiMessageStatistics,
ApiPaymentFormNativeParams,
ApiUpdate,
ApiReportReason,
ApiPhoto,
ApiKeyboardButton,
ApiThemeParameters,
ApiAttachBot,
ApiPhoneCall,
ApiWebSession, ApiWebSession,
ApiPremiumPromo,
ApiTranscription,
ApiInputInvoice,
ApiInvoice,
ApiStickerSetInfo,
ApiChatType,
ApiReceipt,
ApiPaymentCredentials,
ApiConfig,
ApiReaction,
ApiChatReactions,
ApiContact,
ApiExportedInvite,
ApiSendMessageAction,
ApiMessageEntity,
ApiAttachment,
ApiChatBannedRights,
ApiChatAdminRights,
ApiSessionData,
ApiTypingStatus,
} from '../api/types'; } from '../api/types';
import type { import type {
FocusDirection,
ISettings,
MediaViewerOrigin,
ChatCreationProgress,
ProfileEditProgress,
SharedMediaType,
GlobalSearchContent,
ManagementProgress,
PaymentStep,
ShippingOption,
ApiInvoiceContainer, ApiInvoiceContainer,
ApiPrivacyKey, ApiPrivacyKey,
ApiPrivacySettings, ApiPrivacySettings,
ThemeKey,
IThemeSettings,
NotifyException,
LangCode,
EmojiKeywords,
InlineBotSettings,
NewChatMembersProgress,
AudioOrigin, AudioOrigin,
ManagementState, ChatCreationProgress,
SettingsScreens, EmojiKeywords,
FocusDirection,
GlobalSearchContent,
InlineBotSettings,
ISettings,
IThemeSettings,
LangCode,
LoadMoreDirection,
ManagementProgress,
ManagementScreens, ManagementScreens,
LoadMoreDirection, PrivacyVisibility, ManagementState,
MediaViewerOrigin,
NewChatMembersProgress,
NotifyException,
PaymentStep,
PrivacyVisibility,
ProfileEditProgress,
SettingsScreens,
SharedMediaType,
ShippingOption,
ThemeKey,
} from '../types'; } from '../types';
import { typify } from '../lib/teact/teactn';
import type { P2pMessage } from '../lib/secret-sauce'; import type { P2pMessage } from '../lib/secret-sauce';
import type { ApiCredentials } from '../components/payment/PaymentModal'; import type { ApiCredentials } from '../components/payment/PaymentModal';
@ -1364,7 +1364,7 @@ export interface ActionPayloads {
}; };
resetLeftColumnWidth: undefined; resetLeftColumnWidth: undefined;
copySelectedMessages: WithTabId; copySelectedMessages: WithTabId | undefined;
copyMessagesByIds: { copyMessagesByIds: {
messageIds?: number[]; messageIds?: number[];
} & WithTabId; } & WithTabId;
@ -2064,7 +2064,7 @@ export interface ActionPayloads {
loadAttachBots: { loadAttachBots: {
hash?: string; hash?: string;
}; } | undefined;
toggleAttachBot: { toggleAttachBot: {
botId: string; botId: string;
@ -2129,9 +2129,9 @@ export interface ActionPayloads {
}; };
// Misc // Misc
openPollModal: { openPollModal: ({
isQuiz?: boolean; isQuiz?: boolean;
} & WithTabId; } & WithTabId) | undefined;
closePollModal: WithTabId | undefined; closePollModal: WithTabId | undefined;
requestConfetti: ({ requestConfetti: ({
top: number; top: number;
@ -2183,7 +2183,7 @@ export interface ActionPayloads {
toggleGroupCallMute: { toggleGroupCallMute: {
participantId: string; participantId: string;
value: boolean; value: boolean;
}; } | undefined;
toggleGroupCallPresentation: { toggleGroupCallPresentation: {
value?: boolean; value?: boolean;
} | undefined; } | undefined;
@ -2263,14 +2263,14 @@ export interface ActionPayloads {
updateGlobalPrivacySettings: { shouldArchiveAndMuteNewNonContact: boolean }; updateGlobalPrivacySettings: { shouldArchiveAndMuteNewNonContact: boolean };
// Premium // Premium
openPremiumModal: { openPremiumModal: ({
initialSection?: string; initialSection?: string;
fromUserId?: string; fromUserId?: string;
toUserId?: string; toUserId?: string;
isSuccess?: boolean; isSuccess?: boolean;
isGift?: boolean; isGift?: boolean;
monthsAmount?: number; monthsAmount?: number;
} & WithTabId; } & WithTabId) | undefined;
closePremiumModal: ({ closePremiumModal: ({
isClosed?: boolean; isClosed?: boolean;
} & WithTabId) | undefined; } & WithTabId) | undefined;
@ -2281,11 +2281,11 @@ export interface ActionPayloads {
}; };
loadPremiumGifts: undefined; loadPremiumGifts: undefined;
loadDefaultTopicIcons: never; loadDefaultTopicIcons: undefined;
loadPremiumStickers: undefined; loadPremiumStickers: undefined;
loadPremiumSetStickers: { loadPremiumSetStickers: {
hash?: string; hash?: string;
}; } | undefined;
openGiftPremiumModal: ({ openGiftPremiumModal: ({
forUserId?: string; forUserId?: string;
@ -2379,8 +2379,6 @@ export interface ActionPayloads {
} }
export type RequiredGlobalState = GlobalState & { _: never }; export type RequiredGlobalState = GlobalState & { _: never };
const typed = typify<GlobalState, ActionPayloads & RequiredActionPayloads>();
export type GlobalActions = ReturnType<typeof typed.getActions>;
export type ActionReturnType = GlobalState | void | Promise<void>; export type ActionReturnType = GlobalState | void | Promise<void>;
export type TabArgs<T> = T extends RequiredGlobalState ? [ export type TabArgs<T> = T extends RequiredGlobalState ? [
tabId: number, tabId: number,

View File

@ -300,11 +300,14 @@ export function typify<
>() { >() {
type ProjectActionNames = keyof ActionPayloads; type ProjectActionNames = keyof ActionPayloads;
// When payload is allowed to be `undefined` we consider it optional
type ProjectActions = { type ProjectActions = {
[ActionName in ProjectActionNames]: ( [ActionName in ProjectActionNames]:
payload?: ActionPayloads[ActionName], (undefined extends ActionPayloads[ActionName] ? (
options?: ActionOptions, (payload?: ActionPayloads[ActionName], options?: ActionOptions) => void
) => void; ) : (
(payload: ActionPayloads[ActionName], options?: ActionOptions) => void
))
}; };
type ActionHandlers = { type ActionHandlers = {

View File

@ -1,12 +1,12 @@
import type { GlobalActions } from '../global';
import { getActions } from '../global'; import { getActions } from '../global';
import type { GlobalActions } from '../global/types';
const callbacks = new Map<string, number>(); const callbacks = new Map<string, number>();
export default function requestActionTimeout(action: keyof GlobalActions, timeout: number) { export default function requestActionTimeout(action: keyof GlobalActions, timeout: number) {
clearTimeout(callbacks.get(action)); clearTimeout(callbacks.get(action));
const timerId = window.setTimeout(() => { const timerId = window.setTimeout(() => {
getActions()[action](); (getActions()[action] as VoidFunction)();
}, timeout); }, timeout);
callbacks.set(action, timerId); callbacks.set(action, timerId);
} }