import { CompiledMessage } from "./msgfmt.js";
import type { ComponentPlaceholder, InferredMessageType } from "./msgfmt-parser-types.js";
import { ErrorHandler, ErrorLevel } from "./error-handling.js";
export type { ComponentPlaceholder } from "./msgfmt-parser-types.js";
export * from "./errors.js";
export * from "./error-handling.js";
declare const messageBrandSymbol: unique symbol;
declare const translationIdBrandSymbol: unique symbol;
/**
 * A subtype of `string` that represents translation messages.
 *
 * @param Args parameters required by this message
 *
 * @since 0.1.0 (`@hi18n/core`)
 */
export declare type Message<Args = {}> = string & {
    [messageBrandSymbol]: (args: Args) => void;
};
/**
 * A base type for a vocabulary.
 *
 * A vocabulary here means a set of translation ids required for this book of translations.
 *
 * @since 0.1.0 (`@hi18n/core`)
 */
export declare type VocabularyBase = Record<string, Message<any>>;
/**
 * Extracts parameters required by the translated message.
 *
 * @param M the message being instantiated.
 * @param C replacement for the component interpolation (like `<0></0>` or `<link></link>`).
 *
 * @since 0.1.0 (`@hi18n/core`)
 */
export declare type MessageArguments<M extends Message<any>, C> = InstantiateComponentTypes<InjectAdditionalParams<AbstractMessageArguments<M>>, C>;
export declare type InjectAdditionalParams<Args> = true extends HasDate<Args[keyof Args]> ? Args & {
    timeZone: string;
} : Args;
export declare type HasDate<T> = T extends Date ? true : never;
export declare type AbstractMessageArguments<M extends Message<any>> = M extends Message<infer Args> ? Args : never;
export declare type InstantiateComponentTypes<Args, C> = {
    [K in keyof Args]: InstantiateComponentType<Args[K], C>;
};
export declare type InstantiateComponentType<T, C> = T extends ComponentPlaceholder ? C : T;
/**
 * A subtype of `string` that represents a dynamically-managed translation id.
 *
 * @param Vocabulary the vocabulary type of the Book it refers to
 * @param Args parameters required by this message
 *
 * @since 0.1.1 (`@hi18n/core`)
 */
export declare type TranslationId<Vocabulary extends VocabularyBase, Args = {}> = string & {
    [translationIdBrandSymbol]: (catalog: Vocabulary, args: Args) => void;
};
/**
 * Extracts the translation ids that don't take parameters.
 *
 * @param Vocabulary the vocabulary, a set of translation ids we can use for this book of translations.
 * @param K a dummy parameter to do a union distribution
 *
 * @since 0.1.0 (`@hi18n/core`)
 */
export declare type SimpleMessageKeys<Vocabulary extends VocabularyBase, K extends string & keyof Vocabulary = string & keyof Vocabulary> = K extends unknown ? {} extends MessageArguments<Vocabulary[K], never> ? K : never : never;
/**
 * Infers the appropriate type for the translated message.
 *
 * At runtime, it just returns the first argument.
 *
 * @param s the translated message
 * @returns the first argument
 *
 * @since 0.1.0 (`@hi18n/core`)
 *
 * @example
 *   ```ts
 *   export default new Book<Vocabulary>({
 *     "example/greeting": msg("Hello, {name}!"),
 *   });
 *   ```
 */
export declare function msg<S extends string>(s: S): InferredMessageType<S>;
export declare namespace msg {
    var todo: <S extends string>(s: S) => InferredMessageType<S>;
}
/**
 * Marks a translation id as dynamically used with {@link CompoundTranslatorFunction.dynamic t.dynamic}.
 *
 * At runtime, it just returns the second argument.
 *
 * @param book the book the id is linked to. Just discarded at runtime.
 * @param id the translation id.
 * @returns the second argument
 *
 * @since 0.1.1 (`@hi18n/core`)
 *
 * @example
 *   ```ts
 *   const menus = [
 *     {
 *       url: "https://example.com/home",
 *       titleId: translationId(book, "example/navigation/home"),
 *     },
 *     {
 *       url: "https://example.com/map",
 *       titleId: translationId(book, "example/navigation/map"),
 *     },
 *   ];
 *
 *   const { t } = getTranslator(book, "en");
 *   t.dynamic(menus[i].titleId);
 *   ```
 */
export declare function translationId<Vocabulary extends VocabularyBase, K extends string & keyof Vocabulary>(book: Book<Vocabulary>, id: K): TranslationId<Vocabulary, AbstractMessageArguments<Vocabulary[K]>>;
/**
 * A set of translated messages, containing translations for all supported locales.
 *
 * In other words, a book is a set of {@link Catalog}s for all languages.
 *
 * @since 0.1.0 (`@hi18n/core`)
 *
 * @example
 *   ```ts
 *   type Vocabulary = {
 *     "example/greeting": Message<{ name: string }>;
 *   };
 *   export const book = new Book<Vocabulary>({
 *     en: catalogEn,
 *     ja: catalogJa,
 *   });
 *   ```
 *
 * @example You can use `import()` to lazy-load catalogs.
 *   Note that you need to use extra setup to avoid the
 *   "Catalog not loaded" error.
 *
 *   ```ts
 *   type Vocabulary = {
 *     "example/greeting": Message<{ name: string }>;
 *   };
 *   export const book = new Book<Vocabulary>({
 *     en: () => import("./en"),
 *     ja: () => import("./ja"),
 *   });
 *   ```
 */
export declare class Book<Vocabulary extends VocabularyBase> {
    readonly catalogs: Record<string, Catalog<Vocabulary>>;
    readonly _loaders: Readonly<Record<string, Catalog<Vocabulary> | CatalogLoader<Vocabulary>>>;
    _handleError?: ErrorHandler | undefined;
    _implicitLocale?: string | undefined;
    constructor(catalogs: Readonly<Record<string, Catalog<Vocabulary> | CatalogLoader<Vocabulary>>>, options?: BookOptions);
    /**
     * Load a catalog for specific locale.
     *
     * Consider using {@link preloadCatalogs} instead.
     *
     * @param locale locale to load
     *
     * @since 0.1.9 (`@hi18n/core`)
     */
    loadCatalog(locale: string): Promise<void>;
    handleError(e: Error, level: ErrorLevel): void;
}
/**
 * @since 0.1.7 (`@hi18n/core`)
 */
export declare type BookOptions = {
    /**
     * Custom error handler. {@link defaultErrorHandler} is used by default.
     *
     * @example
     *   ```ts
     *   export const book = new Book({
     *     en: catalogEn,
     *     ja: catalogJa,
     *   }, {
     *     handleError(error, level) {
     *       if (level === "error") {
     *         // Report to Sentry or somewhere
     *       } else {
     *         console.warn(error);
     *       }
     *     }
     *   });
     *   ```
     *
     * @since 0.1.7 (`@hi18n/core`)
     */
    handleError?: ErrorHandler | undefined;
    /**
     * Locale fallback to use when no valid locale is specified.
     *
     * @example
     *   ```ts
     *   export const book = new Book({
     *     en: catalogEn,
     *     ja: catalogJa,
     *   }, { implicitLocale: "en" });
     *   ```
     *
     * @since 0.1.7 (`@hi18n/core`)
     */
    implicitLocale?: string | undefined;
};
/**
 * A function to asynchronously load a catalog.
 *
 * It is usually provided as `() => import("...")`.
 *
 * @since 0.1.9 (`@hi18n/core`)
 */
export declare type CatalogLoader<Vocabulary extends VocabularyBase> = () => Promise<{
    default: Catalog<Vocabulary>;
}>;
/**
 * A set of translated messages for a specific locale.
 *
 * @since 0.1.0 (`@hi18n/core`)
 *
 * @example
 *   ```ts
 *   type Vocabulary = {
 *     "example/greeting": Message<{ name: string }>;
 *   };
 *   export default new Catalog<Vocabulary>("en", {
 *     "example/greeting": msg("Hello, {name}!"),
 *   });
 *   ```
 */
export declare class Catalog<Vocabulary extends VocabularyBase> {
    locale?: string | undefined;
    readonly data: Readonly<Vocabulary>;
    private _looseLocale;
    private _compiled;
    /**
     * @since 0.1.6 (`@hi18n/core`)
     */
    constructor(locale: string, data: Readonly<Vocabulary>);
    /**
     * @deprecated deprecated from 0.1.6. Please specify the locale.
     * @since 0.1.0 (`@hi18n/core`)
     */
    constructor(data: Readonly<Vocabulary>);
    getCompiledMessage(id: string & keyof Vocabulary): CompiledMessage;
}
/**
 * An object returned from {@link getTranslator}.
 *
 * @since 0.1.0 (`@hi18n/core`)
 */
export declare type TranslatorObject<Vocabulary extends VocabularyBase> = {
    /**
     * Returns the translated message.
     *
     * @since 0.1.0 (`@hi18n/core`)
     *
     * @example
     *   ```ts
     *   const { t } = getTranslator(book, "en");
     *   t("example/greeting-simple"); // => "Hello!"
     *   ```
     */
    t: CompoundTranslatorFunction<Vocabulary>;
    /**
     * Similar to {@link TranslatorObject.t} but allows component interpolation
     * (i.e. to interpret commands like `<0>foo</0>` or `<link>foo</link>`)
     *
     * Users usually don't need to call it manually.
     * See the `@hi18n/react` package for its application to React.
     *
     * @param id the id of the translation
     * @param interpolator functions to customize the interpolation behavior
     * @param options the parameters of the translation.
     *
     * @since 0.1.0 (`@hi18n/core`)
     */
    translateWithComponents<T, C, K extends string & keyof Vocabulary>(id: K, interpolator: ComponentInterpolator<T, C>, options: MessageArguments<Vocabulary[K], C>): T | string;
};
declare type CompoundTranslatorFunction<Vocabulary extends VocabularyBase> = TranslatorFunction<Vocabulary> & {
    /**
     * Returns the translated message for a dynamic id.
     *
     * @since 0.1.1 (`@hi18n/core`)
     *
     * @example
     *   ```ts
     *   const { t } = getTranslator(book, "en");
     *   t.dynamic(menus[i].titleId); // => "Map"
     *   ```
     */
    dynamic: DynamicTranslatorFunction<Vocabulary>;
    /**
     * Declares a translation to be made.
     *
     * At runtime, it returns the first argument.
     *
     * @param id the id of the translation
     * @param options the parameters of the translation.
     *
     * @since 0.1.1 (`@hi18n/core`)
     *
     * @example
     *   ```ts
     *   const { t } = getTranslator(book, "en");
     *   t.todo("example/greeting-simple"); // => "[TODO: example/greeting-simple]"
     *   ```
     */
    todo(id: string, options?: Record<string, unknown>): string;
};
declare type TranslatorFunction<Vocabulary extends VocabularyBase> = {
    /**
     * Returns the translated message for a simple one.
     *
     * @param id the id of the translation
     *
     * @since 0.1.0 (`@hi18n/core`)
     *
     * @example
     *   ```ts
     *   const { t } = getTranslator(book, "en");
     *   t("example/greeting-simple"); // => "Hello!"
     *   ```
     */
    (id: SimpleMessageKeys<Vocabulary>): string;
    /**
     * Returns the translated message.
     *
     * @param id the id of the translation
     * @param options the parameters of the translation.
     *
     * @since 0.1.0 (`@hi18n/core`)
     *
     * @example
     *   ```ts
     *   const { t } = getTranslator(book, "en");
     *   t("example/greeting", { name: "John" }); // => "Hello, John!"
     *   ```
     */
    <K extends string & keyof Vocabulary>(id: K, options: MessageArguments<Vocabulary[K], never>): string;
};
declare type DynamicTranslatorFunction<Vocabulary extends VocabularyBase> = {
    /**
     * Returns the translated message for a simple dynamic id.
     *
     * @param id the id of the translation
     *
     * @since 0.1.1 (`@hi18n/core`)
     *
     * @example
     *   ```ts
     *   const { t } = getTranslator(book, "en");
     *   t.dynamic(menus[i].titleId); // => "Map"
     *   ```
     */
    (id: TranslationId<Vocabulary, {}>): string;
    /**
     * Returns the translated message for a dynamic id.
     *
     * @param id the id of the translation
     * @param options the parameters of the translation.
     *
     * @since 0.1.1 (`@hi18n/core`)
     *
     * @example
     *   ```ts
     *   const { t } = getTranslator(book, "en");
     *   t.dynamic(greetings[i].translationId, { name: "John" }); // => "Hello, John!"
     *   ```
     */
    <Args>(id: TranslationId<Vocabulary, Args>, options: InstantiateComponentTypes<InjectAdditionalParams<Args>, never>): string;
};
/**
 * Used in {@link TranslatorObject.translateWithComponents} to customize
 * the behavior of component interpolation.
 *
 * @since 0.1.0 (`@hi18n/core`)
 */
export declare type ComponentInterpolator<T, C> = {
    collect: (submessages: (T | string)[]) => T | string;
    wrap: (component: C, message: T | string | undefined) => T | string;
};
/**
 * Retrieves the translation helpers from the book and the locales.
 *
 * @param book the "book" (i.e. the set of translations) containing the desired messages.
 * @param locales a locale or a list of locale in the order of preference (the latter being not supported yet)
 * @param options.throwPromise if true, it throws a Promise instance instead of an error. Used for React Suspense integration.
 * @returns A set of translation helpers
 *
 * @since 0.1.0 (`@hi18n/core`)
 *
 * @example
 *   ```ts
 *   const { t } = getTranslator(book, "en");
 *   t("example/greeting-simple"); // => "Hello!"
 *   ```
 */
export declare function getTranslator<Vocabulary extends VocabularyBase>(book: Book<Vocabulary>, locales: string | string[], options?: GetTranslatorOptions): TranslatorObject<Vocabulary>;
/**
 * options for {@link getTranslator}
 *
 * @since 0.1.9 (`@hi18n/core`)
 */
export declare type GetTranslatorOptions = {
    /** if true, it throws a Promise instance instead of an error. Used for React Suspense integration. */
    throwPromise?: boolean | undefined;
};
/**
 * Starts loading and waits for catalogs so that {@link getTranslator} does not error
 * with "Catalog not loaded" error.
 *
 * It is a wrapper for {@link Book.loadCatalog}.
 *
 * @param book same as {@link getTranslator}'s `book` parameter.
 * @param locales same as {@link getTranslator}'s `locales` parameter.
 *
 * @since 0.1.9 (`@hi18n/core`)
 */
export declare function preloadCatalogs<Vocabulary extends VocabularyBase>(book: Book<Vocabulary>, locales: string | string[]): Promise<void>;
/**
 * A convenience helper to get the default time zone.
 * If you need more sophisticated guess for old browsers,
 * consider using other libraries like `moment.tz.guess`.
 *
 * @returns the default time zone, if anything is found. Otherwise the string "UTC"
 *
 * @since 0.1.3 (`@hi18n/core`)
 */
export declare function getDefaultTimeZone(): string;
//# sourceMappingURL=index.d.ts.map