]> Untitled Git - lemmy-ui.git/commitdiff
Merge branch 'shilangyu-feature/i18n-type-constraint'
authorDessalines <tyhou13@gmx.com>
Mon, 1 Mar 2021 21:25:34 +0000 (16:25 -0500)
committerDessalines <tyhou13@gmx.com>
Mon, 1 Mar 2021 21:25:34 +0000 (16:25 -0500)
generate_translations.js
src/shared/components/no-match.tsx
src/shared/i18next.ts

index 0cab8e3603a5a9fd113363a9255cd3c25c406e68..594f574c3433778551159c28cc8ae5d32369ee6c 100644 (file)
@@ -1,27 +1,68 @@
-fs = require('fs');
+const fs = require("fs");
 
-let translationDir = 'lemmy-translations/translations/';
-let outDir = 'src/shared/translations/';
+const translationDir = "lemmy-translations/translations/";
+const outDir = "src/shared/translations/";
 fs.mkdirSync(outDir, { recursive: true });
 fs.readdir(translationDir, (_err, files) => {
   files.forEach(filename => {
-    const lang = filename.split('.')[0];
+    const lang = filename.split(".")[0];
     try {
       const json = JSON.parse(
-        fs.readFileSync(translationDir + filename, 'utf8')
+        fs.readFileSync(translationDir + filename, "utf8")
       );
-      var data = `export const ${lang} = {\n  translation: {`;
-      for (var key in json) {
+      let data = `export const ${lang} = {\n  translation: {`;
+      for (const key in json) {
         if (key in json) {
           const value = json[key].replace(/"/g, '\\"');
-          data = `${data}\n    ${key}: "${value}",`;
+          data += `\n    ${key}: "${value}",`;
         }
       }
-      data += '\n  },\n};';
-      const target = outDir + lang + '.ts';
+      data += "\n  },\n};";
+      const target = outDir + lang + ".ts";
       fs.writeFileSync(target, data);
     } catch (err) {
       console.error(err);
     }
   });
 });
+
+// generate types for i18n keys
+const baseLanguage = "en";
+
+fs.readFile(`${translationDir}${baseLanguage}.json`, "utf8", (_, fileStr) => {
+  const keys = Object.keys(JSON.parse(fileStr));
+
+  const data = `import { i18n } from "i18next";
+
+declare module "i18next" {
+  export type I18nKeys = 
+${keys.map(key => `    | "${key}"`).join("\n")};
+  
+  export interface TFunctionTyped {
+    // basic usage
+    <
+      TResult extends TFunctionResult = string,
+      TInterpolationMap extends Record<string, unknown> = StringMap
+    >(
+      key: I18nKeys | I18nKeys[],
+      options?: TOptions<TInterpolationMap> | string
+    ): TResult;
+    // overloaded usage
+    <
+      TResult extends TFunctionResult = string,
+      TInterpolationMap extends Record<string, unknown> = StringMap
+    >(
+      key: I18nKeys | I18nKeys[],
+      defaultValue?: string,
+      options?: TOptions<TInterpolationMap> | string
+    ): TResult;
+  }
+
+  export interface i18nTyped extends i18n {
+    t: TFunctionTyped;
+  }
+}
+`;
+
+  fs.writeFileSync(`${outDir}i18next.d.ts`, data);
+});
index b11c0e54571ec1019a5f146cf6ef402fd9c65637..175f4a9b2a7176cdabe0663adbd67ccede87b236 100644 (file)
@@ -1,8 +1,11 @@
+import { I18nKeys } from "i18next";
 import { Component } from "inferno";
 import { i18n } from "../i18next";
 
 export class NoMatch extends Component<any, any> {
-  private errCode = new URLSearchParams(this.props.location.search).get("err");
+  private errCode = new URLSearchParams(this.props.location.search).get(
+    "err"
+  ) as I18nKeys;
 
   constructor(props: any, context: any) {
     super(props, context);
index 8f3000557d578543850bb866f23800454722968b..99dbc70b6c72e4ea6d17fe6b036bef91a500cfe1 100644 (file)
@@ -1,4 +1,4 @@
-import i18next from "i18next";
+import i18next, { i18nTyped } from "i18next";
 import { getLanguage } from "./utils";
 import { en } from "./translations/en";
 import { el } from "./translations/el";
@@ -84,4 +84,6 @@ i18next.init({
   interpolation: { format },
 });
 
-export { i18next as i18n, resources };
+export const i18n = i18next as i18nTyped;
+
+export { resources };