@adrienlcp/i18n 0.1.0 → 0.1.1

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.
@@ -25,6 +25,18 @@ type Localized<Reference> = Dictionary & DictionaryFor<Reference>;
25
25
  type AnyLoader = () => Promise<{
26
26
  default: Dictionary;
27
27
  }>;
28
+ /**
29
+ * Refuses a `defaultLocale` typed as more than one locale. `const
30
+ * DEFAULT_LOCALE: Locale = 'en'` holds `'en'` but is typed `'en' | 'fr'`, which
31
+ * would make the reference every locale's dictionary at once: a second locale's
32
+ * leaves are plain `string`s, so every key with a placeholder would come out as
33
+ * `never` at the call site, far from the cause. The property name is the error
34
+ * TypeScript prints here instead.
35
+ */
36
+ type SingleLocale<DefaultLocale extends string> = IsUnion<DefaultLocale> extends false ? unknown : {
37
+ 'defaultLocale must be typed as one locale, not a union: write `const DEFAULT_LOCALE = "en" satisfies Locale`': never;
38
+ };
39
+ type IsUnion<Member, Whole = Member> = Member extends unknown ? [Whole] extends [Member] ? false : true : never;
28
40
  /**
29
41
  * One locale's entry held to the reference, whichever way it arrives. A loader
30
42
  * is compared through the dictionary its module `export default`s, so a locale
@@ -110,7 +122,7 @@ export type I18n<Reference, Locale extends string, DefaultLocale extends Locale
110
122
  * `load` resolves on the spot.
111
123
  */
112
124
  export declare const createI18n: <const Entries extends Record<string, Dictionary | AnyLoader>, const DefaultLocale extends keyof Entries & string>({ defaultLocale, dictionaries }: {
113
- defaultLocale: DefaultLocale;
125
+ defaultLocale: DefaultLocale & SingleLocale<DefaultLocale>;
114
126
  dictionaries: Entries & { [Locale in keyof Entries]: Matching<Entries[DefaultLocale], Entries[Locale]>; } & Record<DefaultLocale, Localized<Entries[DefaultLocale]>>;
115
127
  }) => I18n<Entries[DefaultLocale], keyof Entries & string, DefaultLocale>;
116
128
  export {};
@@ -38,6 +38,11 @@ export declare const defineDictionary: <const T extends { [Segment in keyof T]:
38
38
  * TypeScript's excess property check does the other half of the work: a key the
39
39
  * reference does not have is rejected at the literal, at every depth.
40
40
  *
41
+ * Only for a dictionary handed to `createTranslator` directly. One registered
42
+ * with `createI18n` is written through `defineDictionary`, like the reference:
43
+ * the annotation widens each message to `string`, and the registry, which
44
+ * compares placeholders, then refuses every message that has one.
45
+ *
41
46
  * ```ts
42
47
  * export const FR_DICTIONARY: DictionaryFor<typeof EN_DICTIONARY> = { … }
43
48
  * ```
package/package.json CHANGED
@@ -24,13 +24,12 @@
24
24
  "type": "git",
25
25
  "url": "git+https://github.com/AdrienLcp/packages.git"
26
26
  },
27
+ "sideEffects": false,
28
+ "type": "module",
29
+ "version": "0.1.1",
27
30
  "scripts": {
28
31
  "build": "tsc -p tsconfig.build.json",
29
- "prepublishOnly": "pnpm build",
30
32
  "test": "vitest run",
31
33
  "test:watch": "vitest --watch"
32
- },
33
- "sideEffects": false,
34
- "type": "module",
35
- "version": "0.1.0"
36
- }
34
+ }
35
+ }