diff --git a/package.json b/package.json index 0209b7aa8..f7d9459cb 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "9.0.0", "description": "Internationalization for react done right. Using the i18next i18n ecosystem.", "main": "dist/commonjs/index.js", - "types": "index.d.ts", + "types": "src/index.d.ts", "jsnext:main": "dist/es/index.js", "module": "dist/es/index.js", "keywords": [ @@ -39,7 +39,6 @@ "@babel/preset-env": "^7.0.0", "@babel/preset-react": "^7.0.0", "@babel/register": "^7.0.0", - "@types/i18next": "^11.9.0", "@types/react": "^16.4.18", "all-contributors-cli": "^5.4.1", "babel-core": "^7.0.0-bridge.0", @@ -58,7 +57,7 @@ "eslint-plugin-jsx-a11y": "6.1.1", "eslint-plugin-prettier": "2.7.0", "eslint-plugin-react": "7.11.1", - "i18next": "11.9.0", + "i18next": "13.1.0", "jest": "23.6.0", "jest-cli": "23.6.0", "mkdirp": "0.5.1", @@ -74,12 +73,14 @@ "rollup-plugin-node-resolve": "3.4.0", "rollup-plugin-terser": "^3.0.0", "sinon": "^6.3.4", + "tslint": "^5.12.0", + "typescript": "^3.2.2", "yargs": "12.0.2" }, "peerDependencies": { "i18next": ">= 6.0.1", - "react": ">= 16.3.0", - "prop-types": ">= 15.6.2" + "prop-types": ">= 15.6.2", + "react": ">= 16.3.0" }, "scripts": { "clean": "rimraf dist && mkdirp dist", @@ -92,11 +93,12 @@ "build": "npm run clean && npm run build:cjs && npm run build:es && npm run build:umd && npm run build:amd && npm run copy", "preversion": "npm run build && git push", "postversion": "git push && git push --tags", - "pretest": "", + "pretest": "npm run test:typescript", "test": "BABEL_ENV=development jest --no-cache", "test:watch": "BABEL_ENV=development jest --no-cache --watch", "test:coverage": "enzyme-adapter-react-install 16 && BABEL_ENV=development jest --no-cache --coverage", "test:lint": "./node_modules/.bin/eslint ./src", + "test:typescript": "tslint --project tsconfig.json && tsc", "contributors:add": "all-contributors add", "contributors:generate": "all-contributors generate" }, diff --git a/index.d.ts b/src/index.d.ts similarity index 88% rename from index.d.ts rename to src/index.d.ts index 0de1107f9..2ed700bda 100644 --- a/index.d.ts +++ b/src/index.d.ts @@ -1,6 +1,5 @@ -import * as React from 'react'; -import i18next from 'i18next'; -import { Context as ReactContext } from 'create-react-context'; +import * as React from "react"; +import i18next from "i18next"; type Omit = Pick>; type Subtract = Omit; @@ -33,14 +32,14 @@ export interface I18nContextValues { lng?: string; } -export const I18nContext: ReactContext; +export const I18nContext: React.Context; export interface WithI18n extends I18nContextValues { i18nOptions?: ReactI18NextOptions; } export function withI18n():

( - Wrapper: React.ComponentType

, + Wrapper: React.ComponentType

) => React.ComponentType>; export interface WithNamespaces extends WithI18n { @@ -64,25 +63,26 @@ interface NamespaceExtractor { export function withNamespaces( namespace?: Namespace | NamespaceExtractor, - options?: WithNamespacesOptions, + options?: WithNamespacesOptions ):

( - component: React.ComponentType

, + component: React.ComponentType

) => React.ComponentType>; export const translate: typeof withNamespaces; export interface NamespacesConsumerProps extends ReactI18NextOptions { ns?: Namespace; + i18n?: i18next.i18n; initialI18nStore?: {}; initialLanguage?: string; - children( + children: ( t: i18next.TranslationFunction, options: { i18n: i18next.i18n; lng: string; ready: boolean; - }, - ): React.ReactNode; + } + ) => React.ReactNode; } export const NamespacesConsumer: React.ComponentClass; diff --git a/test/typescript/NamespacesConsumer.test.tsx b/test/typescript/NamespacesConsumer.test.tsx new file mode 100644 index 000000000..9d073f81f --- /dev/null +++ b/test/typescript/NamespacesConsumer.test.tsx @@ -0,0 +1,12 @@ +import i18next from "i18next"; +import * as React from "react"; +import { NamespacesConsumer } from "../../src/index"; + +function withi18nProp() { + // const i18n = i18next.init({}); + return ( + + {(t) =>

{t("title")}

} + + ); +} diff --git a/test/typescript/examples-react.test.tsx b/test/typescript/examples-react.test.tsx new file mode 100644 index 000000000..76f9bd11d --- /dev/null +++ b/test/typescript/examples-react.test.tsx @@ -0,0 +1,58 @@ +import * as React from "react"; +import { + NamespacesConsumer, + Trans, + withNamespaces, + WithNamespaces, +} from "../../src/index"; + +// Component using the render prop NamespacesConsumer +// get t function inside the component +// learn more: https://react.i18next.com/components/namespacesconsumer +function Welcome() { + return ( + + {(t, { i18n }) =>

{t("title")}

} +
+ ); +} + +// Component using the higher order component withNamespaces +// pass t function via props into the component +// learn more: https://react.i18next.com/components/withnamespaces +function MyComponent({ t }: WithNamespaces) { + return ( + + To get started, edit src/App.js and save to reload. + + ); +} +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) +class App extends React.Component { + public render() { + const { t, i18n } = this.props; + + const changeLanguage = (lng: string) => { + i18n.changeLanguage(lng); + }; + + return ( +
+
+ + + +
+
+ +
+
{t("description.part2")}
+
+ ); + } +} +export default withNamespaces("translation")(App); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..d05ee9205 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "lib": ["es2015", "dom"], + "jsx": "react", + "baseUrl": ".", + "noEmit": true, + "strict": true + }, + "include": ["./src/**/*", "./test/**/*"] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 000000000..9e97bd249 --- /dev/null +++ b/tslint.json @@ -0,0 +1,7 @@ +{ + "defaultSeverity": "error", + "extends": ["tslint:recommended"], + "jsRules": {}, + "rules": {}, + "rulesDirectory": [] +}