import type { ElementType } from 'react'; import type { Dictionary } from '../localization/locales'; import type { LOCALE_DEFAULTS } from '../localization/constants'; /** The dictionary of localized strings */ export type LocalizerDictionary = Dictionary; /** A localization dictionary key */ export type LocalizerToken = keyof Dictionary; /** A dynamic argument that can be used in a localized string */ export type DynamicArg = string | number; /** A record of dynamic arguments for a specific key in the localization dictionary */ export type ArgsRecord = Record, DynamicArg>; // TODO: create a proper type for this export type DictionaryWithoutPluralStrings = Dictionary; export type PluralKey = 'count'; export type PluralString = `{${string}, plural, one [${string}] other [${string}]}`; /** The dynamic arguments in a localized string */ type DynamicArgs = /** If a string follows the plural format use its plural variable name and recursively check for * dynamic args inside all plural forms */ LocalizedString extends `{${infer PluralVar}, plural, one [${infer PluralOne}] other [${infer PluralOther}]}` ? PluralVar | DynamicArgs | DynamicArgs : /** If a string segment follows the variable form parse its variable name and recursively * check for more dynamic args */ LocalizedString extends `${string}{${infer Var}}${infer Rest}` ? Var | DynamicArgs : never; export type ArgsRecordExcludingDefaults = Omit< ArgsRecord, keyof typeof LOCALE_DEFAULTS >; /** The arguments for retrieving a localized message */ export type GetMessageArgs = T extends LocalizerToken ? DynamicArgs extends never ? [T] : ArgsRecordExcludingDefaults extends Record ? [T] : [T, ArgsRecordExcludingDefaults] : never; /** Basic props for all calls of the Localizer component */ type LocalizerComponentBaseProps = { token: T; asTag?: ElementType; className?: string; }; /** The props for the localization component */ export type LocalizerComponentProps = T extends LocalizerToken ? DynamicArgs extends never ? LocalizerComponentBaseProps : ArgsRecordExcludingDefaults extends Record ? LocalizerComponentBaseProps : LocalizerComponentBaseProps & { args: ArgsRecordExcludingDefaults } : never; export type LocalizerComponentPropsObject = LocalizerComponentProps; export type I18nMethods = { /** @see {@link window.i18n.stripped} */ stripped: ( ...[token, args]: GetMessageArgs ) => R | T; /** @see {@link window.i18n.inEnglish} */ inEnglish: ( ...[token, args]: GetMessageArgs ) => R | T; /** @see {@link window.i18n.formatMessageWithArgs */ getRawMessage: ( ...[token, args]: GetMessageArgs ) => R | T; /** @see {@link window.i18n.formatMessageWithArgs} */ formatMessageWithArgs: ( rawMessage: R, args?: ArgsRecord ) => R; }; export type SetupI18nReturnType = I18nMethods & (( ...[token, args]: GetMessageArgs ) => R);