intor-translator 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,265 +1,383 @@
1
- import { LocaleNamespaceMessages, Locale, RichReplacement, FallbackLocalesMap, Replacement } from 'intor-types';
2
-
3
1
  /**
4
- * Represents the available locale namespaces from the message map.
2
+ * Represents a locale identifier, such as 'en', 'zh-TW', or 'fr-FR'.
5
3
  *
6
- * Extracts top-level keys from the entire localized message structure,
7
- * which are typically used as namespace identifiers (e.g., "common", "home", "dashboard").
4
+ * @example
5
+ * const locale: Locale = "en";
6
+ */
7
+ type Locale = string;
8
+ /**
9
+ * Represents a message namespace.
10
+ * Typically used to group related messages, such as 'common', 'auth', or 'dashboard'.
8
11
  *
9
- * @template Messages - The type of the locale message map.
12
+ * @example
13
+ * const namespace: Namespace = "dashboard";
10
14
  */
11
- type RawLocale<Messages extends LocaleNamespaceMessages> = keyof Messages & string;
15
+ type Namespace = string;
12
16
  /**
13
- * Computes all possible nested key paths of a deeply nested object.
17
+ * Represents a single translatable message string.
14
18
  *
15
- * Example:
16
- * ```ts
17
- * {
18
- * a: {
19
- * b: {
20
- * c: "hello";
21
- * };
22
- * };
23
- * }
24
- * ```
25
- * Will generate: `"a" | "a.b" | "a.b.c"`
19
+ * @example
20
+ * const message: Message = "Hello World";
21
+ */
22
+ type Message = string;
23
+ /**
24
+ * A recursive replacement object used for interpolating values in message templates.
26
25
  *
27
- * Useful for type-safe translation key autocompletion and validation.
26
+ * Each key maps to a value that can be a string, number, or another nested `Replacement`.
27
+ * This structure supports deep replacements such as `user.profile.link`.
28
28
  *
29
- * @template Messages - The message object to extract nested key paths from.
29
+ * @example
30
+ * const replacements: Replacement = {
31
+ * name: "intor",
32
+ * count: 5,
33
+ * user: {
34
+ * profile: {
35
+ * link: "https://example.com/avatar.png"
36
+ * }
37
+ * }
38
+ * };
30
39
  */
31
- type NestedKeyPaths<Messages> = Messages extends object ? {
32
- [Key in keyof Messages]: `${Key & string}` | `${Key & string}.${NestedKeyPaths<Messages[Key]>}`;
33
- }[keyof Messages] : never;
40
+ type Replacement = {
41
+ [key: string]: string | number | Replacement;
42
+ };
34
43
 
35
- type TranslatorHandlers = {
36
- /**
37
- * A custom formatter function to format translation messages.
38
- * You can use this to integrate ICU libraries like `intl-messageformat`.
39
- */
40
- messageFormatter?: MessageFormatter;
41
- /**
42
- * Handler for loading state of the translation message.
43
- * Useful when translations are loaded asynchronously.
44
- */
45
- loadingMessageHandler?: LoadingMessageHandler;
46
- /**
47
- * Handler for placeholders in translation messages.
48
- * Useful for handling missing or fallback placeholders.
49
- */
50
- placeholderHandler?: PlaceholderHandler;
44
+ /** Represents primitive types supported in rich replacements. */
45
+ type RichPrimitive = string | number | boolean | Date;
46
+ /** Represents serializable objects that provide a custom string representation. */
47
+ type RichSerializable = {
48
+ toString(): string;
51
49
  };
50
+ /** A formatter function that takes a string chunk and returns any formatted output. */
51
+ type RichFormatterFunction = (value: unknown, ...args: unknown[]) => unknown;
52
+ /**
53
+ * Possible value types for rich replacements.
54
+ * Can be a primitive, serializable object, formatter function, or null/undefined.
55
+ */
56
+ type ReplacementValue = RichPrimitive | RichSerializable | RichFormatterFunction | null | undefined;
52
57
  /**
53
- * Custom formatter for translation messages.
58
+ * A recursive replacement object that supports rich replacement values,
59
+ * allowing complex nested interpolation structures.
54
60
  *
55
- * This function receives the raw message and context to produce a formatted result.
56
- * You can use this to integrate ICU-style formatting or other complex message processing.
61
+ * @example
62
+ * const replacements: RichReplacement = {
63
+ * name: "Alice",
64
+ * age: 30,
65
+ * isActive: true,
66
+ * birthday: new Date("1993-04-25"),
67
+ * formatter: (value, ...args) => `<b>${value}</b>`,
68
+ * nested: {
69
+ * score: 100,
70
+ * note: null,
71
+ * },
72
+ * };
73
+ */
74
+ type RichReplacement = {
75
+ [key: string]: ReplacementValue;
76
+ };
77
+
78
+ /**
79
+ * A nested message structure or a simple string message.
80
+ * Used to represent either a plain message or an object containing more nested messages.
57
81
  *
58
- * @template Result - The type of the formatted result.
82
+ * @example
83
+ * const greeting: NestedMessage = "Hello";
59
84
  *
60
- * @param ctx - The context object containing information for formatting.
61
- * @param ctx.message - The raw message string to format.
62
- * @param ctx.locale - The currently active locale string (e.g. 'en-US').
63
- * @param ctx.key - The translation key associated with this message.
64
- * @param ctx.replacements - Optional replacement values for variables inside the message.
85
+ * const userMessages: NestedMessage = {
86
+ * profile: {
87
+ * greeting: "Hello, user!",
88
+ * farewell: "Goodbye!"
89
+ * }
90
+ * };
91
+ */
92
+ type NestedMessage = Message | {
93
+ [key: string]: NestedMessage;
94
+ };
95
+ /**
96
+ * A record of messages where keys are strings, and values can be strings or nested message objects.
97
+ * Supports deep message trees like `errors.form.required`.
65
98
  *
66
- * @returns The formatted message, usually a string but can be any type.
99
+ * @example
100
+ * const messages: MessageRecord = {
101
+ * greeting: "Hello",
102
+ * user: {
103
+ * profile: {
104
+ * name: "Your Name"
105
+ * }
106
+ * }
107
+ * };
67
108
  */
68
- type MessageFormatter<Result = unknown> = (ctx: TranslatorHandlerContext & {
69
- message: string;
70
- }) => Result;
109
+ type MessageRecord = Record<string, NestedMessage>;
71
110
  /**
72
- * Handler function called when translation message is loading.
111
+ * A record of messages grouped by namespace.
112
+ * Each namespace contains its own `MessageRecord` structure.
73
113
  *
74
- * @template Result - The type of the loading handler result.
114
+ * @example
115
+ * const namespaceMessages: NamespaceMessages = {
116
+ * common: {
117
+ * hello: "Hello",
118
+ * goodbye: "Goodbye"
119
+ * },
120
+ * auth: {
121
+ * login: {
122
+ * success: "Login successful"
123
+ * }
124
+ * }
125
+ * };
126
+ */
127
+ type NamespaceMessages = Record<Namespace, NestedMessage>;
128
+ /**
129
+ * Messages grouped by locale and then by namespace.
130
+ * Used to structure all available messages for multiple locales and namespaces.
75
131
  *
76
- * @param ctx - The context object containing locale, key, and replacements.
77
- * @returns Result to display during loading (e.g. a placeholder string or React element).
132
+ * @example
133
+ * const messages: LocaleNamespaceMessages = {
134
+ * en: {
135
+ * common: {
136
+ * welcome: "Welcome"
137
+ * },
138
+ * auth: {
139
+ * login: {
140
+ * success: "Login successful"
141
+ * }
142
+ * }
143
+ * },
144
+ * "zh-TW": {
145
+ * common: {
146
+ * welcome: "歡迎"
147
+ * }
148
+ * }
149
+ * };
78
150
  */
79
- type LoadingMessageHandler<Result = unknown> = (ctx: TranslatorHandlerContext) => Result;
151
+ type LocaleNamespaceMessages = Record<Locale, NamespaceMessages>;
80
152
  /**
81
- * Handler function for placeholders in translation messages.
153
+ * Merges messages from all locales into a single unified structure.
82
154
  *
83
- * @template Result - The type of the placeholder handler result.
155
+ * @example
156
+ * const messages = {
157
+ * en: { auth: { login: "Login" } },
158
+ * zh: { auth: { logout: "登出" } },
159
+ * };
84
160
  *
85
- * @param ctx - The context object containing locale, key, and replacements.
86
- * @returns Result to display for placeholders (e.g. a default string or React element).
161
+ * type Result = UnionLocaleMessages<typeof messages>;
162
+ * // Result: { auth: { login: "Login" } } | { auth: { logout: "登出" } }
87
163
  */
88
- type PlaceholderHandler<Result = unknown> = (ctx: TranslatorHandlerContext) => Result;
164
+ type UnionLocaleMessages<M extends LocaleNamespaceMessages> = M[LocaleKey<M>];
165
+
89
166
  /**
90
- * Context object passed to translation handlers.
91
- * Contains necessary information for formatting or handling translation messages.
167
+ * Extracts the locale keys from the messages object as string literals.
168
+ *
169
+ * @example
170
+ * type Locales = LocaleKey<{
171
+ * en: {};
172
+ * "zh-TW": {};
173
+ * }>;
174
+ * // Locales is "en" | "zh-TW"
92
175
  */
93
- type TranslatorHandlerContext = {
94
- locale: Locale;
95
- key: string;
96
- replacements?: RichReplacement;
97
- };
98
-
176
+ type LocaleKey<M extends LocaleNamespaceMessages> = keyof M & string;
99
177
  /**
100
- * - Options for creating a translator instance.
178
+ * A map that defines fallback locales for each base locale.
179
+ *
180
+ * When a message is missing for a given locale, the system will attempt to find the message
181
+ * by falling back to the locales listed here, in the specified order.
101
182
  *
102
183
  * @example
103
- * ```ts
104
- * const options: TranslatorOptions = {
105
- * locale: 'en',
106
- * messages: {
107
- * en: { common: { hello: "Hello" } },
108
- * zh: { common: { hello: "你好" } },
109
- * },
110
- * fallbackLocales: { zh: ['en'] },
111
- * handlers: {
112
- * messageFormatter: ({ message }) => message.toUpperCase(),
113
- * },
184
+ * const fallbacks: FallbackLocalesMap = {
185
+ * "en-AU": ["en-GB", "en"],
186
+ * "zh-TW": ["zh-HK", "zh"]
114
187
  * };
115
- * ```
116
188
  */
117
- type TranslatorOptions<Messages extends LocaleNamespaceMessages> = {
118
- /**
119
- * - The message definitions to be used by the translator.
120
- * - These should be pre-loaded and structured by locale and namespace.
121
- */
122
- messages: Readonly<Messages>;
123
- /**
124
- * - The current active locale, e.g., "en" or "zh-TW".
125
- */
126
- locale: RawLocale<Messages>;
127
- /**
128
- * - Optional fallback locale(s) to use when a message is missing in the primary locale.
129
- */
130
- fallbackLocales?: FallbackLocalesMap;
131
- /**
132
- * - Whether the translator is currently in a loading state.
133
- * - Useful for SSR or async loading scenarios.
134
- */
135
- isLoading?: boolean;
136
- /**
137
- * - The message string to return while in loading state.
138
- * - Will be overridden if you provide a `loadingMessageHandler` in handlers.
139
- */
140
- loadingMessage?: string;
141
- /**
142
- * - A fallback string to show when the message key is missing.
143
- * - Will be overridden if you provide a `placeholderHandler` in handlers.
144
- */
145
- placeholder?: string;
146
- /**
147
- * - Optional handlers to customize translation behavior (formatting, placeholders, etc).
148
- */
149
- handlers?: TranslatorHandlers;
150
- };
151
-
152
- type GetLocale<Messages extends LocaleNamespaceMessages> = () => RawLocale<Messages>;
153
-
154
- type GetMessages<Messages extends LocaleNamespaceMessages> = () => Readonly<Messages>;
155
-
156
- type HasKey<Messages extends LocaleNamespaceMessages> = {
157
- <Locale extends RawLocale<Messages>>(key: NestedKeyPaths<Messages[Locale]>, locale?: Locale): boolean;
158
- (key: string, locale?: Locale): boolean;
159
- };
160
- type LooseHasKey = (key?: string, locale?: Locale) => boolean;
161
-
162
- type Translate<Messages extends LocaleNamespaceMessages> = {
163
- <Locale extends RawLocale<Messages>>(key: NestedKeyPaths<Messages[Locale]>, replacements?: Replacement | RichReplacement): string;
164
- (key: string, replacements?: Replacement | RichReplacement): string;
165
- };
166
- type LooseTranslate = (key?: string, replacements?: Replacement | RichReplacement) => string;
167
-
168
- type Scoped<Messages extends LocaleNamespaceMessages> = <Locale extends RawLocale<Messages>>(preKey?: NestedKeyPaths<Messages[Locale]>) => {
169
- t: LooseTranslate;
170
- hasKey: LooseHasKey;
171
- };
172
-
173
- type SetLocale<Messages extends LocaleNamespaceMessages> = (newLocale: RawLocale<Messages>) => void;
189
+ type FallbackLocalesMap<L extends string = string> = Partial<Record<L, L[]>>;
174
190
 
175
191
  /**
176
- * The main Translator interface providing all core i18n methods.
192
+ * Gets all dot-separated keys (including non-leaf nodes) from a nested object.
177
193
  *
178
- * This interface is the foundation of the `intor` i18n engine, giving access
179
- * to all translation utilities and state management.
194
+ * @example
195
+ * NodeKeys<{ a: { b: { c: string }, d: string } }> → "a" | "a.b" | "a.b.c" | "a.d"
196
+ */
197
+ type NodeKeys<M> = M extends object ? {
198
+ [K in keyof M]: K extends string ? `${K}` | `${K}.${NodeKeys<M[K]>}` : never;
199
+ }[keyof M] : never;
200
+ /**
201
+ * Default maximum recursive depth for nested key type computations,
202
+ * balancing type safety and compiler performance.
203
+ */
204
+ type DefaultDepth = 15;
205
+ /** Countdown tuple for limiting recursive depth (up to 10 levels). */
206
+ type Prev = [
207
+ never,
208
+ 0,
209
+ 1,
210
+ 2,
211
+ 3,
212
+ 4,
213
+ 5,
214
+ 6,
215
+ 7,
216
+ 8,
217
+ 9,
218
+ 10,
219
+ 11,
220
+ 12,
221
+ 13,
222
+ 14,
223
+ 15,
224
+ 16,
225
+ 17,
226
+ 18,
227
+ 19,
228
+ 20
229
+ ];
230
+ /**
231
+ * Gets dot-separated keys to string leaf nodes in a nested object.
180
232
  *
181
- * @typeParam Messages - The full shape of all available locale messages.
182
- * Defaults to `LocaleNamespaceMessages`.
233
+ * @example
234
+ * LeafKeys<{ a: { b: "x", c: { d: "y" } } }> → "a.b" | "a.c.d"
183
235
  */
184
- type Translator<Messages extends LocaleNamespaceMessages = LocaleNamespaceMessages> = {
185
- /**
186
- * Get the current active locale.
187
- *
188
- * @returns The current locale string (e.g., "en", "zh-TW").
189
- */
190
- getLocale: GetLocale<Messages>;
191
- /**
192
- * Set the current locale.
193
- *
194
- * @param locale - The new locale to switch to.
195
- */
196
- setLocale: SetLocale<Messages>;
197
- /**
198
- * Get all messages for the current locale.
199
- *
200
- * @returns The messages object containing all translation namespaces and keys.
201
- */
202
- getMessages: GetMessages<Messages>;
203
- /**
204
- * Translate a message by its key with optional replacements.
205
- *
206
- * This function is fully type-safe, ensuring that translation keys are valid
207
- * according to the loaded locale messages.
208
- *
209
- * You can use autocompletion and strict checking for nested message keys
210
- * by providing the locale type.
211
- *
212
- * @example
213
- * ```ts
214
- * t("home.welcome.title"); // Fully typed with key autocompletion
215
- * t("dashboard.stats.count", { count: 5 });
216
- * ```
217
- *
218
- * @param key - A dot-separated translation key (e.g., `"common.hello"`).
219
- * @param replacements - Optional values to replace placeholders in the message.
220
- * @returns The translated message string.
221
- */
222
- t: Translate<Messages>;
223
- /**
224
- * Check whether a strongly-typed translation key exists in the loaded messages.
225
- *
226
- * This method ensures the key path is valid according to the message schema
227
- * for a given locale.
228
- *
229
- * @example
230
- * ```ts
231
- * hasKey("home.welcome.title"); // true or false
232
- * hasKey("dashboard.stats.count", "zh");
233
- * ```
234
- *
235
- * @param key - A dot-separated message key defined in the locale messages.
236
- * @param locale - Optional locale to check against. If omitted, defaults to current locale.
237
- * @returns A boolean indicating whether the key exists.
238
- */
239
- hasKey: HasKey<Messages>;
240
- /**
241
- * Create a scoped translator bound to a specific namespace.
242
- *
243
- * Useful for modular translation logic (e.g., per-page or per-component).
244
- *
245
- * @param namespace - The namespace to scope to (e.g., "auth").
246
- * @returns A new translator with scoped `t()` and helpers.
247
- */
248
- scoped: Scoped<Messages>;
249
- };
236
+ type LeafKeys<M, D extends number = DefaultDepth> = [D] extends [never] ? never : M extends object ? {
237
+ [K in keyof M]: M[K] extends string ? `${K & string}` : M[K] extends object ? `${K & string}.${LeafKeys<M[K], Prev[D]>}` : never;
238
+ }[keyof M] : never;
239
+ /**
240
+ * Gets string leaf keys from all locale messages combined.
241
+ *
242
+ * @example
243
+ * UnionLocaleLeafKeys<{ en: { a: { b: "x" } }, zh: { a: { c: "y" } } }> → "a.b" | "a.c"
244
+ */
245
+ type UnionLocaleLeafKeys<M extends LocaleNamespaceMessages, D extends number = DefaultDepth> = UnionLocaleMessages<M> extends NamespaceMessages ? LeafKeys<UnionLocaleMessages<M>, D> : never;
246
+ /**
247
+ * Resolves the type at a dot-separated key in a nested object.
248
+ *
249
+ * @example
250
+ * ResolvePathType<{ a: { b: { c: string } } }, "a.b.c"> → string
251
+ * ResolvePathType<{ a: { b: { c: "hello" } } }, "a.b.c"> → "hello"
252
+ */
253
+ type ResolvePathType<T, P extends string> = P extends `${infer Head}.${infer Tail}` ? Head extends keyof T ? ResolvePathType<T[Head], Tail> : never : P extends keyof T ? T[P] : never;
254
+ /**
255
+ * Extracts leaf keys under a scoped path (K) from all locales combined.
256
+ *
257
+ * @example
258
+ * type Messages = {
259
+ * en: { auth: { login: { success: string } } },
260
+ * zh: { auth: { login: { success: string; failed: string } } }
261
+ * };
262
+ * ScopedLeafKeys<Messages, "auth.login"> "success" | "failed"
263
+ */
264
+ type ScopedLeafKeys<M extends LocaleNamespaceMessages, K extends string, D extends number = DefaultDepth> = UnionLocaleMessages<M> extends infer ResolvedLocaleMessages ? ResolvedLocaleMessages extends object ? LeafKeys<ResolvePathType<ResolvedLocaleMessages, K>, D> : never : never;
250
265
 
251
266
  /**
252
- * Factory function to create a translator instance.
267
+ * A ref object holding all localized messages by locale.
253
268
  *
254
- * This function sets up a full-featured translator object based on the provided options,
255
- * including locale management, message retrieval, key existence checking, translation,
256
- * and scoped translations with prefixes.
269
+ * @example
270
+ * const messagesRef: MessagesRef<AllMessages> = {
271
+ * current: {
272
+ * en: { home: { title: "Welcome" } },
273
+ * zh: { home: { title: "歡迎" } }
274
+ * }
275
+ * };
276
+ */
277
+ type MessagesRef<M extends LocaleNamespaceMessages> = {
278
+ current: Readonly<M>;
279
+ };
280
+ /**
281
+ * A ref object holding the currently selected locale.
257
282
  *
258
- * @template Messages - The shape of the locale namespace messages supported by this translator.
283
+ * @example
284
+ * const localeRef: LocaleRef<AllMessages> = {
285
+ * current: "en"
286
+ * };
287
+ */
288
+ type LocaleRef<M extends LocaleNamespaceMessages> = {
289
+ current: LocaleKey<M>;
290
+ };
291
+ /**
292
+ * A ref object indicating whether translation is loading.
259
293
  *
260
- * @param translatorOptions - Configuration options including initial locale and messages.
261
- * @returns A translator instance exposing locale control and translation methods.
294
+ * @example
295
+ * const isLoadingRef: IsLoadingRef = {
296
+ * current: true
297
+ * };
262
298
  */
263
- declare function createTranslator<Messages extends LocaleNamespaceMessages>(translatorOptions: TranslatorOptions<Messages>): Translator<Messages>;
299
+ type IsLoadingRef = {
300
+ current: boolean;
301
+ };
302
+
303
+ /** Config options for translation behavior. */
304
+ type TranslateConfig = {
305
+ fallbackLocales?: FallbackLocalesMap;
306
+ loadingMessage?: string;
307
+ placeholder?: string;
308
+ handlers?: TranslateHandlers;
309
+ };
310
+ /** Optional handler functions for customizing translation behavior. */
311
+ type TranslateHandlers = {
312
+ formatMessage?: FormatMessage;
313
+ onLoading?: OnLoading;
314
+ onMissing?: OnMissing;
315
+ };
316
+ /** Format a resolved message before returning it. */
317
+ type FormatMessage<Result = unknown> = (ctx: TranslateContext & {
318
+ message: string;
319
+ }) => Result;
320
+ /** Called when translation is still loading. */
321
+ type OnLoading<Result = unknown> = (ctx: TranslateContext) => Result;
322
+ /** Called when no message is found for the given key. */
323
+ type OnMissing<Result = unknown> = (ctx: TranslateContext) => Result;
324
+ /**
325
+ * Context passed to translation-related functions.
326
+ * @example
327
+ * {
328
+ * locale: "en",
329
+ * key: "home.title",
330
+ * replacements: { name: "Yiming" }
331
+ * }
332
+ */
333
+ type TranslateContext = {
334
+ locale: Locale;
335
+ key: string;
336
+ replacements?: Replacement | RichReplacement;
337
+ };
338
+
339
+ interface BaseTranslatorOptions<M extends LocaleNamespaceMessages> {
340
+ messages: Readonly<M>;
341
+ locale: LocaleKey<M>;
342
+ }
343
+
344
+ declare class BaseTranslator<M extends LocaleNamespaceMessages> {
345
+ protected options: BaseTranslatorOptions<M>;
346
+ protected messagesRef: MessagesRef<M>;
347
+ protected localeRef: LocaleRef<M>;
348
+ constructor(options: BaseTranslatorOptions<M>);
349
+ /** Get all message data. */
350
+ get messages(): M;
351
+ /** Replace messages with new ones. */
352
+ setMessages(messages: M): void;
353
+ /** Get the current active locale. */
354
+ get locale(): LocaleKey<M>;
355
+ /** Change the active locale if available. */
356
+ setLocale(newLocale: LocaleKey<M>): boolean;
357
+ /** Check if a key exists in the specified locale or current locale. */
358
+ hasKey: (key: UnionLocaleLeafKeys<M>, targetLocale?: LocaleKey<M>) => boolean;
359
+ }
360
+
361
+ interface CoreTranslatorOptions<M extends LocaleNamespaceMessages> extends BaseTranslatorOptions<M>, TranslateConfig {
362
+ }
363
+
364
+ declare class CoreTranslator<M extends LocaleNamespaceMessages> extends BaseTranslator<M> {
365
+ protected options: CoreTranslatorOptions<M>;
366
+ protected isLoadingRef: IsLoadingRef;
367
+ constructor(options: CoreTranslatorOptions<M>);
368
+ /** Get the current loading state. */
369
+ get isLoading(): boolean;
370
+ /** Set the loading state. */
371
+ setLoading(state: boolean): void;
372
+ t: <Result = string>(key: UnionLocaleLeafKeys<M>, replacements?: Replacement | RichReplacement) => Result;
373
+ }
374
+
375
+ declare class ScopeTranslator<M extends LocaleNamespaceMessages> extends CoreTranslator<M> {
376
+ constructor(options: CoreTranslatorOptions<M>);
377
+ scoped: <K extends NodeKeys<UnionLocaleMessages<M>> & string, ScopedKeys extends ScopedLeafKeys<M, K> & string>(preKey: K) => {
378
+ hasKey: (key?: ScopedKeys | undefined, targetLocale?: string) => boolean;
379
+ t: (key?: ScopedKeys | undefined, replacements?: Replacement | RichReplacement) => string;
380
+ };
381
+ }
264
382
 
265
- export { type LoadingMessageHandler, type MessageFormatter, type PlaceholderHandler, type Translator, type TranslatorHandlers, createTranslator };
383
+ export { type FallbackLocalesMap, type FormatMessage, type IsLoadingRef, type LeafKeys, type Locale, type LocaleKey, type LocaleNamespaceMessages, type LocaleRef, type Message, type MessageRecord, type MessagesRef, type Namespace, type NamespaceMessages, type NestedMessage, type NodeKeys, type OnLoading, type OnMissing, type Replacement, type RichReplacement, type ScopedLeafKeys, type TranslateConfig, type TranslateContext, type TranslateHandlers, ScopeTranslator as Translator, type UnionLocaleLeafKeys, type UnionLocaleMessages };