From 6bf2e162cb517774ebad731589ad63415d7a2d52 Mon Sep 17 00:00:00 2001 From: tkow Date: Tue, 8 Jan 2019 15:05:05 +0900 Subject: [PATCH 01/11] add generic type to t function and the tests --- src/index.d.ts | 12 +++++++++--- test/typescript/NamespacesConsumer.test.tsx | 16 +++++++++++++--- test/typescript/examples-react.test.tsx | 5 ++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index 2ed700bda..7eccd60a5 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -26,7 +26,9 @@ export function getI18n(): i18next.i18n; export interface I18nContextValues { i18n: i18next.i18n; - t: i18next.TranslationFunction; + t + (key: TKeys | TKeys[], options?: i18next.TranslationOptions): + ReturnType>; defaultNS?: string; reportNS?: string; lng?: string; @@ -76,7 +78,9 @@ export interface NamespacesConsumerProps extends ReactI18NextOptions { initialI18nStore?: {}; initialLanguage?: string; children: ( - t: i18next.TranslationFunction, + t: + (key: TKeys | TKeys[], options?: i18next.TranslationOptions) => + ReturnType>, options: { i18n: i18next.i18n; lng: string; @@ -101,7 +105,9 @@ export interface TransProps { count?: number; parent?: React.ReactNode; i18n?: i18next.i18n; - t?: i18next.TranslationFunction; + t? + (key: TKeys | TKeys[], options?: i18next.TranslationOptions): + ReturnType>; defaults?: string; values?: {}; components?: React.ReactNode[]; diff --git a/test/typescript/NamespacesConsumer.test.tsx b/test/typescript/NamespacesConsumer.test.tsx index 9d073f81f..a7c51e3ef 100644 --- a/test/typescript/NamespacesConsumer.test.tsx +++ b/test/typescript/NamespacesConsumer.test.tsx @@ -2,11 +2,21 @@ import i18next from "i18next"; import * as React from "react"; import { NamespacesConsumer } from "../../src/index"; +type TKeys = "title" | "text"; + function withi18nProp() { // const i18n = i18next.init({}); return ( - - {(t) =>

{t("title")}

} -
+
+ + {(t) => +
+

{t("title")}

+
{t("text")}
+
{t("none")}
+
+ } +
+
); } diff --git a/test/typescript/examples-react.test.tsx b/test/typescript/examples-react.test.tsx index 76f9bd11d..223113cd0 100644 --- a/test/typescript/examples-react.test.tsx +++ b/test/typescript/examples-react.test.tsx @@ -32,6 +32,7 @@ const MyComponentWrapped = withNamespaces()(MyComponent); // the app gets passed in t and i18n by using same hoc withNamespaces // using i18n.changeLanguage you can change the language programmatically // (same is possible using the NamespacesConsumer render prop - just read the docs) +type TKeys = "description.part1" | "description.part2"; class App extends React.Component { public render() { const { t, i18n } = this.props; @@ -50,7 +51,9 @@ class App extends React.Component {
-
{t("description.part2")}
+
{t("description.part1")}
+
{t("description.part2")}
+
{t("description.part2", {interpolate: "interpolate" } )}
); } From 0889c353fa35b92d931c147cb3999a94761cb550 Mon Sep 17 00:00:00 2001 From: tkow Date: Wed, 9 Jan 2019 23:52:53 +0900 Subject: [PATCH 02/11] rollback test --- test/typescript/NamespacesConsumer.test.tsx | 16 +++------------- test/typescript/examples-react.test.tsx | 5 +---- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/test/typescript/NamespacesConsumer.test.tsx b/test/typescript/NamespacesConsumer.test.tsx index a7c51e3ef..9d073f81f 100644 --- a/test/typescript/NamespacesConsumer.test.tsx +++ b/test/typescript/NamespacesConsumer.test.tsx @@ -2,21 +2,11 @@ import i18next from "i18next"; import * as React from "react"; import { NamespacesConsumer } from "../../src/index"; -type TKeys = "title" | "text"; - function withi18nProp() { // const i18n = i18next.init({}); return ( -
- - {(t) => -
-

{t("title")}

-
{t("text")}
-
{t("none")}
-
- } -
-
+ + {(t) =>

{t("title")}

} +
); } diff --git a/test/typescript/examples-react.test.tsx b/test/typescript/examples-react.test.tsx index 223113cd0..76f9bd11d 100644 --- a/test/typescript/examples-react.test.tsx +++ b/test/typescript/examples-react.test.tsx @@ -32,7 +32,6 @@ const MyComponentWrapped = withNamespaces()(MyComponent); // the app gets passed in t and i18n by using same hoc withNamespaces // using i18n.changeLanguage you can change the language programmatically // (same is possible using the NamespacesConsumer render prop - just read the docs) -type TKeys = "description.part1" | "description.part2"; class App extends React.Component { public render() { const { t, i18n } = this.props; @@ -51,9 +50,7 @@ class App extends React.Component {
-
{t("description.part1")}
-
{t("description.part2")}
-
{t("description.part2", {interpolate: "interpolate" } )}
+
{t("description.part2")}
); } From c2532aa506942474ed83c370d5e6ecc7c891cd6c Mon Sep 17 00:00:00 2001 From: tkow Date: Thu, 10 Jan 2019 00:01:36 +0900 Subject: [PATCH 03/11] change: some omitted typing --- src/index.d.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index 7eccd60a5..ed49c3a94 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -14,6 +14,11 @@ interface ReactI18nextModule { init: (instance: i18next.i18n) => void; } +interface ReactI18nextTranslateFunction { + t + (key: TKeys | TKeys[], options?: i18next.TranslationOptions):TResult; +} + export const reactI18nextModule: ReactI18nextModule; export function setDefaults(options: ReactI18NextOptions): void; @@ -24,11 +29,8 @@ export function setI18n(instance: i18next.i18n): void; export function getI18n(): i18next.i18n; -export interface I18nContextValues { +export interface I18nContextValues extends ReactI18nextTranslateFunction{ i18n: i18next.i18n; - t - (key: TKeys | TKeys[], options?: i18next.TranslationOptions): - ReturnType>; defaultNS?: string; reportNS?: string; lng?: string; @@ -78,9 +80,7 @@ export interface NamespacesConsumerProps extends ReactI18NextOptions { initialI18nStore?: {}; initialLanguage?: string; children: ( - t: - (key: TKeys | TKeys[], options?: i18next.TranslationOptions) => - ReturnType>, + t: ReactI18nextTranslateFunction['t'], options: { i18n: i18next.i18n; lng: string; @@ -100,14 +100,11 @@ export interface I18nextProviderProps { export const I18nextProvider: React.ComponentClass; -export interface TransProps { +export interface TransProps extends Partial{ i18nKey?: string; count?: number; parent?: React.ReactNode; i18n?: i18next.i18n; - t? - (key: TKeys | TKeys[], options?: i18next.TranslationOptions): - ReturnType>; defaults?: string; values?: {}; components?: React.ReactNode[]; From f82bf5fd643424c71e28aaf702c8e71420854ddf Mon Sep 17 00:00:00 2001 From: tkow Date: Thu, 10 Jan 2019 00:25:12 +0900 Subject: [PATCH 04/11] add new test for generic translate function --- .../GenericTlanslateFunction.test.tsx | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/typescript/GenericTlanslateFunction.test.tsx diff --git a/test/typescript/GenericTlanslateFunction.test.tsx b/test/typescript/GenericTlanslateFunction.test.tsx new file mode 100644 index 000000000..f212cb97e --- /dev/null +++ b/test/typescript/GenericTlanslateFunction.test.tsx @@ -0,0 +1,73 @@ +import * as React from "react"; +import { + NamespacesConsumer, + Trans, + withNamespaces, + WithNamespaces, +} from "../../src/index"; + +type TKeys = "title" | "text"; + +function NamespacesConsumerTest() { + return ( + + {(t, { i18n }) => +
+

{t("title")}

+ {t("any")} + {t("text")} + {t("text", {key: "foo"})} +
+ } +
+ ); +} + +function TransComponentTest({ t }: WithNamespaces) { + return ( +
+ + To get started, edit src/App.js and save to reload. + + + To get started, ("title")}>{{name}}and save to reload. + +
+ ); +} + +const MyComponentWrapped = withNamespaces()(TransComponentTest); + +type ArticleKeys = "article.part1" | "article.part2"; +type AnotherArticleKeys = "anotherArticle.part1" | "anotherArticle.part2"; +class App extends React.Component { + public render() { + const { t, i18n } = this.props; + + const changeLanguage = (lng: string) => { + i18n.changeLanguage(lng); + }; + + return ( +
+
+ + + +
+
+ +
+
+
{t("article.part1")}
+
{t("article.part2")}
+
+
+
{t("anotherArticle.part1")}
+
{t("anotherArticle.part2")}
+
+
+ ); + } +} +export default withNamespaces("translation")(App); From 77f66e2075ff08f87b0ec5f64d29262ce10cd510 Mon Sep 17 00:00:00 2001 From: tkow Date: Thu, 10 Jan 2019 00:35:47 +0900 Subject: [PATCH 05/11] add an example and override test --- test/typescript/GenericTlanslateFunction.test.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/typescript/GenericTlanslateFunction.test.tsx b/test/typescript/GenericTlanslateFunction.test.tsx index f212cb97e..2da0370e9 100644 --- a/test/typescript/GenericTlanslateFunction.test.tsx +++ b/test/typescript/GenericTlanslateFunction.test.tsx @@ -8,6 +8,10 @@ import { type TKeys = "title" | "text"; +declare interface IWithNamespacesOverrideTest extends WithNamespaces { + t(a: T): any; +} + function NamespacesConsumerTest() { return ( @@ -15,6 +19,7 @@ function NamespacesConsumerTest() {

{t("title")}

{t("any")} + {t("any", {anyObject: {}})} {t("text")} {t("text", {key: "foo"})}
From 5b532536736f2cae5930c117eea17b1c2cbb9799 Mon Sep 17 00:00:00 2001 From: tkow Date: Thu, 10 Jan 2019 14:43:27 +0900 Subject: [PATCH 06/11] chane inteface for TranslationFunction structured --- src/index.d.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index ed49c3a94..567e7c588 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -14,11 +14,6 @@ interface ReactI18nextModule { init: (instance: i18next.i18n) => void; } -interface ReactI18nextTranslateFunction { - t - (key: TKeys | TKeys[], options?: i18next.TranslationOptions):TResult; -} - export const reactI18nextModule: ReactI18nextModule; export function setDefaults(options: ReactI18NextOptions): void; @@ -29,7 +24,7 @@ export function setI18n(instance: i18next.i18n): void; export function getI18n(): i18next.i18n; -export interface I18nContextValues extends ReactI18nextTranslateFunction{ +export interface I18nContextValues extends i18next.WithT { i18n: i18next.i18n; defaultNS?: string; reportNS?: string; @@ -80,7 +75,7 @@ export interface NamespacesConsumerProps extends ReactI18NextOptions { initialI18nStore?: {}; initialLanguage?: string; children: ( - t: ReactI18nextTranslateFunction['t'], + t: i18next.TranslationFunction, options: { i18n: i18next.i18n; lng: string; @@ -100,7 +95,7 @@ export interface I18nextProviderProps { export const I18nextProvider: React.ComponentClass; -export interface TransProps extends Partial{ +export interface TransProps extends Partial{ i18nKey?: string; count?: number; parent?: React.ReactNode; From e277dca1baa9bd1b75848ac605ed5c3dea3e29fc Mon Sep 17 00:00:00 2001 From: tkow Date: Thu, 10 Jan 2019 16:11:53 +0900 Subject: [PATCH 07/11] change way to inherit type because of lacking of generic parameters. --- src/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.d.ts b/src/index.d.ts index 567e7c588..3520e33c5 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -75,7 +75,7 @@ export interface NamespacesConsumerProps extends ReactI18NextOptions { initialI18nStore?: {}; initialLanguage?: string; children: ( - t: i18next.TranslationFunction, + t: i18next.WithT['t'], options: { i18n: i18next.i18n; lng: string; From a789b47c3f819221ce9d307b18432615b174c719 Mon Sep 17 00:00:00 2001 From: tkow Date: Thu, 10 Jan 2019 16:15:08 +0900 Subject: [PATCH 08/11] add test example --- .../GenericTlanslateFunction.test.tsx | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/test/typescript/GenericTlanslateFunction.test.tsx b/test/typescript/GenericTlanslateFunction.test.tsx index 2da0370e9..0b52f2ea4 100644 --- a/test/typescript/GenericTlanslateFunction.test.tsx +++ b/test/typescript/GenericTlanslateFunction.test.tsx @@ -8,10 +8,6 @@ import { type TKeys = "title" | "text"; -declare interface IWithNamespacesOverrideTest extends WithNamespaces { - t(a: T): any; -} - function NamespacesConsumerTest() { return ( @@ -45,7 +41,17 @@ const MyComponentWrapped = withNamespaces()(TransComponentTest); type ArticleKeys = "article.part1" | "article.part2"; type AnotherArticleKeys = "anotherArticle.part1" | "anotherArticle.part2"; -class App extends React.Component { + +/** + * + * Overload can enable completion of args by without specifying TypeParameters + */ +interface IOverloadedWithNamespaces extends WithNamespaces { + t(key: ArticleKeys, b?: object): any; + t(key: T, b: {name: string}): any; +} + +class App extends React.Component { public render() { const { t, i18n } = this.props; @@ -64,12 +70,12 @@ class App extends React.Component {
-
{t("article.part1")}
-
{t("article.part2")}
+
{t("article.part1", {name: "foo"})}
+
{t("article.part2")}
-
{t("anotherArticle.part1")}
-
{t("anotherArticle.part2")}
+
{t("anotherArticle.part1", {name: "foo"})}
+
{t("anotherArticle.part2", {name: "bar"})}
); From 276d34f5077c2557f7952572ec26e020384412d1 Mon Sep 17 00:00:00 2001 From: tkow Date: Fri, 18 Jan 2019 12:12:29 +0900 Subject: [PATCH 09/11] change peerDependencies to 13.1.3 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index da4fd5bc7..78579d461 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "eslint-plugin-jsx-a11y": "6.1.1", "eslint-plugin-prettier": "2.7.0", "eslint-plugin-react": "7.11.1", - "i18next": "13.1.0", + "i18next": "^13.1.4", "jest": "23.6.0", "jest-cli": "23.6.0", "mkdirp": "0.5.1", @@ -78,7 +78,7 @@ "yargs": "12.0.2" }, "peerDependencies": { - "i18next": ">= 6.0.1", + "i18next": ">= 13.1.3", "react": ">= 16.3.0" }, "scripts": { From bb2827496656e6f763dc54c62e982c7755bbd641 Mon Sep 17 00:00:00 2001 From: tkow Date: Fri, 18 Jan 2019 12:33:26 +0900 Subject: [PATCH 10/11] add more example and make comments concise --- test/typescript/GenericTlanslateFunction.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/typescript/GenericTlanslateFunction.test.tsx b/test/typescript/GenericTlanslateFunction.test.tsx index 0b52f2ea4..0f6b1be27 100644 --- a/test/typescript/GenericTlanslateFunction.test.tsx +++ b/test/typescript/GenericTlanslateFunction.test.tsx @@ -18,6 +18,7 @@ function NamespacesConsumerTest() { {t("any", {anyObject: {}})} {t("text")} {t("text", {key: "foo"})} + {t("text", {key: "bar"})} }
@@ -43,8 +44,7 @@ type ArticleKeys = "article.part1" | "article.part2"; type AnotherArticleKeys = "anotherArticle.part1" | "anotherArticle.part2"; /** - * - * Overload can enable completion of args by without specifying TypeParameters + * Overload makes completion of arguments by without specifying type parameters */ interface IOverloadedWithNamespaces extends WithNamespaces { t(key: ArticleKeys, b?: object): any; From 04997e72eeed9154846bc7d4a12e44d6659b8864 Mon Sep 17 00:00:00 2001 From: tkow Date: Fri, 18 Jan 2019 14:28:41 +0900 Subject: [PATCH 11/11] adapt test new lint rules --- test/typescript/GenericTlanslateFunction.test.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/typescript/GenericTlanslateFunction.test.tsx b/test/typescript/GenericTlanslateFunction.test.tsx index 0f6b1be27..7a0b5d194 100644 --- a/test/typescript/GenericTlanslateFunction.test.tsx +++ b/test/typescript/GenericTlanslateFunction.test.tsx @@ -4,7 +4,7 @@ import { Trans, withNamespaces, WithNamespaces, -} from "../../src/index"; +} from 'react-i18next'; type TKeys = "title" | "text"; @@ -46,13 +46,15 @@ type AnotherArticleKeys = "anotherArticle.part1" | "anotherArticle.part2"; /** * Overload makes completion of arguments by without specifying type parameters */ -interface IOverloadedWithNamespaces extends WithNamespaces { +interface OverloadedWithNamespaces extends WithNamespaces { t(key: ArticleKeys, b?: object): any; + // NOTION: disable no-unnecessary-generics for generic test + // tslint:disable-next-line:no-unnecessary-generics t(key: T, b: {name: string}): any; } -class App extends React.Component { - public render() { +class App extends React.Component { + render() { const { t, i18n } = this.props; const changeLanguage = (lng: string) => {