i18next 26.2.0 → 26.3.0
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/.claude/settings.local.json +3 -1
- package/dist/esm/package.json +1 -1
- package/index.d.ts +1 -0
- package/package.json +1 -1
- package/typescript/options.d.ts +234 -149
- package/typescript/t.d.ts +16 -12
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
"Bash(python3 -c \"import json,sys; print\\(json.load\\(sys.stdin\\)['version']\\)\")",
|
|
16
16
|
"Bash(npm test *)",
|
|
17
17
|
"Bash(git pull *)",
|
|
18
|
-
"Bash(git push *)"
|
|
18
|
+
"Bash(git push *)",
|
|
19
|
+
"Bash(gh api *)",
|
|
20
|
+
"Bash(curl -s \"https://raw.githubusercontent.com/GabenGar/todos/d6d77cef716fcdc5a3991f84605176f85a69cdc8/apps/frontend/src/lib/internationalization/augs.d.ts\")"
|
|
19
21
|
],
|
|
20
22
|
"additionalDirectories": [
|
|
21
23
|
"/Users/adrai/Projects/i18next/react-i18next",
|
package/dist/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"26.
|
|
1
|
+
{"type":"module","version":"26.3.0"}
|
package/index.d.ts
CHANGED
package/package.json
CHANGED
package/typescript/options.d.ts
CHANGED
|
@@ -27,161 +27,246 @@ import type { $MergeBy, $PreservedValue, $Dictionary } from './helpers.js';
|
|
|
27
27
|
*/
|
|
28
28
|
export interface CustomTypeOptions {}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Per-package namespace types for monorepos. Augment this in each package's
|
|
32
|
+
* `i18next.d.ts` instead of `CustomTypeOptions.resources` when several packages
|
|
33
|
+
* need their own namespaces — otherwise TypeScript reports TS2717 on merge.
|
|
34
|
+
*
|
|
35
|
+
* Works alongside the legacy `CustomTypeOptions.resources` field; both end up
|
|
36
|
+
* in `TypeOptions['resources']`.
|
|
37
|
+
*
|
|
38
|
+
* Scalar type options like `defaultNS`, `returnNull`, `enableSelector`, etc.,
|
|
39
|
+
* still belong on `CustomTypeOptions` — this interface is for namespace
|
|
40
|
+
* resource types only.
|
|
41
|
+
*
|
|
42
|
+
* @see https://github.com/i18next/i18next/issues/2409
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* // packages/ui/i18next.d.ts
|
|
47
|
+
* declare module 'i18next' {
|
|
48
|
+
* interface ResourceNamespaceMap {
|
|
49
|
+
* '@repo/ui': typeof uiTranslations;
|
|
50
|
+
* }
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export interface ResourceNamespaceMap {}
|
|
55
|
+
|
|
30
56
|
/**
|
|
31
57
|
* This interface can be augmented by users to add types to `i18next` default PluginOptions.
|
|
32
58
|
*/
|
|
33
59
|
export interface CustomPluginOptions {}
|
|
34
60
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
61
|
+
type _LegacyResources = CustomTypeOptions extends { resources: infer R } ? R : object;
|
|
62
|
+
|
|
63
|
+
// Per-property merge of two object types. Unlike `L & R`, which TypeScript
|
|
64
|
+
// collapses to `never` whenever ANY property has incompatible literals (so a
|
|
65
|
+
// single same-key/different-literal conflict wipes out the whole namespace),
|
|
66
|
+
// this iterates keys and intersects them individually — the conflicting key
|
|
67
|
+
// becomes `never`, the rest survive.
|
|
68
|
+
type _PerPropMerge<L, R> = {
|
|
69
|
+
[K in keyof L | keyof R]: K extends keyof L
|
|
70
|
+
? K extends keyof R
|
|
71
|
+
? L[K] & R[K]
|
|
72
|
+
: L[K]
|
|
73
|
+
: K extends keyof R
|
|
74
|
+
? R[K]
|
|
75
|
+
: never;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Drop properties whose value resolved to `never`. Without this, the
|
|
79
|
+
// conflict key would leak into `keyof Resources[ns]`, then poison
|
|
80
|
+
// `KeysBuilder` recursion (it tries to walk a `never` value) and break
|
|
81
|
+
// `t()` overload resolution for the entire namespace.
|
|
82
|
+
// NOTE: must use the `Pick<T, NonNeverKeys>` form. A `[K in keyof T as ...]`
|
|
83
|
+
// remap does NOT eagerly evaluate `T[K]` for intersection types, so conflict
|
|
84
|
+
// keys would survive the filter.
|
|
85
|
+
type _NonNeverKeys<T> = {
|
|
86
|
+
[K in keyof T]: [T[K]] extends [never] ? never : K;
|
|
87
|
+
}[keyof T];
|
|
88
|
+
type _DropConflictKeys<T> = Pick<T, _NonNeverKeys<T>>;
|
|
89
|
+
|
|
90
|
+
// When the same namespace exists on both sides, deep-merge per property and
|
|
91
|
+
// strip same-key/different-literal conflicts. Otherwise pick from whichever
|
|
92
|
+
// side has it.
|
|
93
|
+
type _MergeNamespaces<L, R> = {
|
|
94
|
+
[K in keyof L | keyof R]: K extends keyof L
|
|
95
|
+
? K extends keyof R
|
|
96
|
+
? _DropConflictKeys<_PerPropMerge<L[K], R[K]>>
|
|
97
|
+
: L[K]
|
|
98
|
+
: K extends keyof R
|
|
99
|
+
? R[K]
|
|
100
|
+
: never;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// NOTE: empty legacy + empty registry must stay `object` so unconfigured projects
|
|
104
|
+
// still get `$IsResourcesDefined === false`.
|
|
105
|
+
type _MergedResources = [keyof _LegacyResources] extends [never]
|
|
106
|
+
? [keyof ResourceNamespaceMap] extends [never]
|
|
107
|
+
? object
|
|
108
|
+
: ResourceNamespaceMap
|
|
109
|
+
: [keyof ResourceNamespaceMap] extends [never]
|
|
110
|
+
? _LegacyResources
|
|
111
|
+
: _MergeNamespaces<_LegacyResources, ResourceNamespaceMap>;
|
|
69
112
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
113
|
+
export type TypeOptions = $MergeBy<
|
|
114
|
+
$MergeBy<
|
|
115
|
+
{
|
|
116
|
+
/** @see {InitOptions.returnNull} */
|
|
117
|
+
returnNull: false;
|
|
118
|
+
|
|
119
|
+
/** @see {InitOptions.returnEmptyString} */
|
|
120
|
+
returnEmptyString: true;
|
|
121
|
+
|
|
122
|
+
/** @see {InitOptions.returnObjects} */
|
|
123
|
+
returnObjects: false;
|
|
124
|
+
|
|
125
|
+
/** @see {InitOptions.keySeparator} */
|
|
126
|
+
keySeparator: '.';
|
|
127
|
+
|
|
128
|
+
/** @see {InitOptions.nsSeparator} */
|
|
129
|
+
nsSeparator: ':';
|
|
130
|
+
|
|
131
|
+
/** @see {InitOptions.pluralSeparator} */
|
|
132
|
+
pluralSeparator: '_';
|
|
133
|
+
|
|
134
|
+
/** @see {InitOptions.contextSeparator} */
|
|
135
|
+
contextSeparator: '_';
|
|
136
|
+
|
|
137
|
+
/** @see {InitOptions.defaultNS} */
|
|
138
|
+
defaultNS: 'translation';
|
|
139
|
+
|
|
140
|
+
/** @see {InitOptions.fallbackNS} */
|
|
141
|
+
fallbackNS: false;
|
|
142
|
+
|
|
143
|
+
/** @see {InitOptions.compatibilityJSON} */
|
|
144
|
+
compatibilityJSON: 'v4';
|
|
145
|
+
|
|
146
|
+
/** @see {InitOptions.resources} */
|
|
147
|
+
resources: object;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Flag that allows HTML elements to receive objects. This is only useful for React applications
|
|
151
|
+
* where you pass objects to HTML elements so they can be replaced to their respective interpolation
|
|
152
|
+
* values (mostly with Trans component)
|
|
153
|
+
*/
|
|
154
|
+
allowObjectInHTMLChildren: false;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Flag that enables strict key checking even if a `defaultValue` has been provided.
|
|
158
|
+
* This ensures all calls of `t` function don't accidentally use implicitly missing keys.
|
|
159
|
+
*/
|
|
160
|
+
strictKeyChecks: false;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Prefix for interpolation
|
|
164
|
+
*/
|
|
165
|
+
interpolationPrefix: '{{';
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Suffix for interpolation
|
|
169
|
+
*/
|
|
170
|
+
interpolationSuffix: '}}';
|
|
171
|
+
|
|
172
|
+
/** @see {InterpolationOptions.unescapePrefix} */
|
|
173
|
+
unescapePrefix: '-';
|
|
174
|
+
|
|
175
|
+
/** @see {InterpolationOptions.unescapeSuffix} */
|
|
176
|
+
unescapeSuffix: '';
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Whether to extract interpolation variables from translation strings at
|
|
180
|
+
* the type level. When `true` (default), the type system parses each
|
|
181
|
+
* resource value for `{{variable}}` patterns and types the `t()` options
|
|
182
|
+
* accordingly.
|
|
183
|
+
*
|
|
184
|
+
* Set to `false` when your translation strings use a different
|
|
185
|
+
* interpolation syntax that the i18next type extractor cannot understand
|
|
186
|
+
* — e.g. ICU MessageFormat plurals like `{count, plural, one {{count} row}
|
|
187
|
+
* other {{count} rows}}` would otherwise produce phantom variable names
|
|
188
|
+
* because the default extractor naively matches the outermost `{{` …
|
|
189
|
+
* `}}`. This flag is type-only; runtime interpolation is governed by
|
|
190
|
+
* `InterpolationOptions` and is unaffected.
|
|
191
|
+
*
|
|
192
|
+
* Required by `i18next-icu` users — see that package's docs for the
|
|
193
|
+
* recommended `CustomTypeOptions` augmentation.
|
|
194
|
+
*
|
|
195
|
+
* @default true
|
|
196
|
+
*/
|
|
197
|
+
parseInterpolation: true;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Use a proxy-based selector to select a translation.
|
|
201
|
+
*
|
|
202
|
+
* Enables features like go-to definition, and better DX/faster autocompletion
|
|
203
|
+
* for TypeScript developers.
|
|
204
|
+
*
|
|
205
|
+
* If you're working with an especially large set of translations and aren't
|
|
206
|
+
* using context, you set `enableSelector` to `"optimize"` and i18next won't do
|
|
207
|
+
* any type-level processing of your translations at all.
|
|
208
|
+
*
|
|
209
|
+
* With `enableSelector` set to `"optimize"`, i18next is capable of supporting
|
|
210
|
+
* arbitrarily large/deep translation sets without causing any IDE slowdown
|
|
211
|
+
* whatsoever.
|
|
212
|
+
*
|
|
213
|
+
* Set `enableSelector` to `"strict"` to require an explicit namespace as the
|
|
214
|
+
* first selector path segment in every call. The selector proxy stops
|
|
215
|
+
* exposing the primary namespace's keys flat on `$` — even
|
|
216
|
+
* `useTranslation('only')` must use `$.only.foo`, never `$.foo`. At runtime,
|
|
217
|
+
* a leading segment matching the scope's namespace list (primary included)
|
|
218
|
+
* is always rewritten as a namespace prefix, fully decoupling selector
|
|
219
|
+
* shape from resolution scope. Use this when you want a single mental model
|
|
220
|
+
* for selector paths regardless of how many namespaces a hook was created
|
|
221
|
+
* with, and to remove the silent miss that flat-primary paths can otherwise
|
|
222
|
+
* cause in multi-ns hooks (see [#2429](https://github.com/i18next/i18next/issues/2429)).
|
|
223
|
+
*
|
|
224
|
+
* `"strict"` mode is incompatible with the `"optimize"` shortcut. If you
|
|
225
|
+
* have keys whose names match sibling namespaces (the
|
|
226
|
+
* [#2405](https://github.com/i18next/i18next/issues/2405) pattern), do not
|
|
227
|
+
* enable strict mode — the leading-segment rewrite would route those keys
|
|
228
|
+
* into the wrong namespace.
|
|
229
|
+
*
|
|
230
|
+
* @default false
|
|
231
|
+
*/
|
|
232
|
+
enableSelector: false;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Maps interpolation format specifiers to their expected value types.
|
|
236
|
+
*
|
|
237
|
+
* By default, i18next infers types from built-in formatter names:
|
|
238
|
+
* - `number`, `currency` → `number`
|
|
239
|
+
* - `datetime` → `Date`
|
|
240
|
+
* - `relativetime` → `number`
|
|
241
|
+
* - `list` → `readonly string[]`
|
|
242
|
+
* - No format specifier → `string | number` (since i18next stringifies values at runtime)
|
|
243
|
+
*
|
|
244
|
+
* Use this option to add mappings for custom formatters or to override
|
|
245
|
+
* the built-in defaults.
|
|
246
|
+
*
|
|
247
|
+
* @default {} (empty — built-in defaults apply)
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```ts
|
|
251
|
+
* interface CustomTypeOptions {
|
|
252
|
+
* interpolationFormatTypeMap: {
|
|
253
|
+
* // custom formatter
|
|
254
|
+
* uppercase: string;
|
|
255
|
+
* // override built-in
|
|
256
|
+
* currency: string;
|
|
257
|
+
* };
|
|
258
|
+
* }
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
interpolationFormatTypeMap: {};
|
|
262
|
+
},
|
|
263
|
+
CustomTypeOptions
|
|
264
|
+
>,
|
|
265
|
+
// HACK: apply merged resources *after* CustomTypeOptions so registry contributions
|
|
266
|
+
// survive when CustomTypeOptions.resources is also defined. Without this
|
|
267
|
+
// second step, the inner $MergeBy would replace the default `resources: object`
|
|
268
|
+
// with CustomTypeOptions['resources'] alone, dropping the registry namespaces.
|
|
269
|
+
{ resources: _MergedResources }
|
|
185
270
|
>;
|
|
186
271
|
|
|
187
272
|
export type PluginOptions<T> = $MergeBy<
|
package/typescript/t.d.ts
CHANGED
|
@@ -77,19 +77,23 @@ interface Branded<Ns extends Namespace> {
|
|
|
77
77
|
/** ****************************************************
|
|
78
78
|
* Build all keys and key prefixes based on Resources *
|
|
79
79
|
***************************************************** */
|
|
80
|
-
type KeysBuilderWithReturnObjects<Res, Key = keyof Res> =
|
|
81
|
-
?
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
type KeysBuilderWithReturnObjects<Res, Key = keyof Res> = [Res] extends [never]
|
|
81
|
+
? never
|
|
82
|
+
: Key extends keyof Res
|
|
83
|
+
? Res[Key] extends $Dictionary | readonly unknown[]
|
|
84
|
+
?
|
|
85
|
+
| JoinKeys<Key, WithOrWithoutPlural<keyof $OmitArrayKeys<Res[Key]>>>
|
|
86
|
+
| JoinKeys<Key, KeysBuilderWithReturnObjects<Res[Key]>>
|
|
87
|
+
: never
|
|
88
|
+
: never;
|
|
87
89
|
|
|
88
|
-
type KeysBuilderWithoutReturnObjects<Res, Key = keyof $OmitArrayKeys<Res>> =
|
|
89
|
-
?
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
type KeysBuilderWithoutReturnObjects<Res, Key = keyof $OmitArrayKeys<Res>> = [Res] extends [never]
|
|
91
|
+
? never
|
|
92
|
+
: Key extends keyof Res
|
|
93
|
+
? Res[Key] extends $Dictionary | readonly unknown[]
|
|
94
|
+
? JoinKeys<Key, KeysBuilderWithoutReturnObjects<Res[Key]>>
|
|
95
|
+
: Key
|
|
96
|
+
: never;
|
|
93
97
|
|
|
94
98
|
type KeysBuilder<Res, WithReturnObjects> = $IsResourcesDefined extends true
|
|
95
99
|
? WithReturnObjects extends true
|