Skip to content

Commit

Permalink
fix: Fix types for appWithTranslation (#1987)
Browse files Browse the repository at this point in the history
  • Loading branch information
oddsund committed Oct 25, 2022
1 parent b47e9d3 commit 73de76d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 40 deletions.
12 changes: 9 additions & 3 deletions src/appWithTranslation.server.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { I18nextProvider } from 'react-i18next'
import { renderToString } from 'react-dom/server'

import { appWithTranslation } from './appWithTranslation'
import { AppProps } from 'next/app'

jest.mock('fs', () => ({
existsSync: jest.fn(),
Expand All @@ -27,10 +28,15 @@ jest.mock('react-i18next', () => ({
__esmodule: true,
}))

const MyApp = ({ Component, pageProps }: AppProps<{ example: string }>) => {
Component
pageProps
return (
<div>Hello world</div>
)
}

const DummyApp = appWithTranslation(() => (
<div>Hello world</div>
))
const DummyApp = appWithTranslation(MyApp)

const props = {
pageProps: {
Expand Down
20 changes: 6 additions & 14 deletions src/appWithTranslation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,15 @@ import { SSRConfig, UserConfig } from './types'
import { i18n as I18NextClient } from 'i18next'
export { Trans, useTranslation, withTranslation } from 'react-i18next'

type AppProps = NextJsAppProps & {
pageProps: SSRConfig
}

export let globalI18n: I18NextClient | null = null

export const appWithTranslation = <Props extends AppProps = AppProps>(
export const appWithTranslation = <Props extends NextJsAppProps>(
WrappedComponent: React.ComponentType<Props>,
configOverride: UserConfig | null = null,
) => {
const AppWithTranslation = (props: Props) => {
const { _nextI18Next } = props.pageProps as SSRConfig
let locale: string | null =
const AppWithTranslation = (props: Props & { pageProps: Props['pageProps'] & SSRConfig }) => {
const { _nextI18Next } = props.pageProps
let locale: string | undefined =
_nextI18Next?.initialLocale ?? props?.router?.locale
const ns = _nextI18Next?.ns

Expand All @@ -34,16 +30,12 @@ export const appWithTranslation = <Props extends AppProps = AppProps>(
const i18n: I18NextClient | null = useMemo(() => {
if (!_nextI18Next && !configOverride) return null

let userConfig = configOverride ?? _nextI18Next?.userConfig
const userConfig = configOverride ?? _nextI18Next?.userConfig

if (!userConfig && configOverride === null) {
if (!userConfig) {
throw new Error('appWithTranslation was called without a next-i18next config')
}

if (configOverride !== null) {
userConfig = configOverride
}

if (!userConfig?.i18n) {
throw new Error('appWithTranslation was called without config.i18n')
}
Expand Down
42 changes: 21 additions & 21 deletions src/serverSideTranslations.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ describe('serverSideTranslations', () => {
expect(fs.existsSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/en-US'))
expect(fs.readdirSync).toHaveBeenCalledTimes(2)
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/en-US'))
expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
'en-US': {
common: {},
'namespace-of-en-US': {},
},
})
expect(props._nextI18Next.ns).toEqual(['common', 'namespace-of-en-US'])
expect(props._nextI18Next?.ns).toEqual(['common', 'namespace-of-en-US'])
})

it('returns all namespaces with fallbackLng (as string)', async () => {
Expand All @@ -101,7 +101,7 @@ describe('serverSideTranslations', () => {
expect(fs.readdirSync).toHaveBeenCalledTimes(4)
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/en-US'))
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/fr'))
expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
'en-US': {
common: {},
Expand All @@ -114,7 +114,7 @@ describe('serverSideTranslations', () => {
'namespace-of-fr': {},
},
})
expect(props._nextI18Next.ns).toStrictEqual(['common', 'namespace-of-en-US', 'namespace-of-fr'])
expect(props._nextI18Next?.ns).toStrictEqual(['common', 'namespace-of-en-US', 'namespace-of-fr'])
})

it('returns all namespaces with fallbackLng (as array)', async () => {
Expand All @@ -131,7 +131,7 @@ describe('serverSideTranslations', () => {
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/en-US'))
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/en'))
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/fr'))
expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
en: {
common: {},
Expand All @@ -152,7 +152,7 @@ describe('serverSideTranslations', () => {
'namespace-of-fr': {},
},
})
expect(props._nextI18Next.ns).toEqual([
expect(props._nextI18Next?.ns).toEqual([
'common',
'namespace-of-en-US',
'namespace-of-en',
Expand All @@ -173,7 +173,7 @@ describe('serverSideTranslations', () => {
expect(fs.readdirSync).toHaveBeenCalledTimes(4)
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/en-US'))
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/fr'))
expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
'en-US': {
common: {},
Expand All @@ -186,7 +186,7 @@ describe('serverSideTranslations', () => {
'namespace-of-fr': {},
},
})
expect(props._nextI18Next.ns).toEqual([
expect(props._nextI18Next?.ns).toEqual([
'common',
'namespace-of-en-US',
'namespace-of-fr',
Expand All @@ -206,7 +206,7 @@ describe('serverSideTranslations', () => {
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/de-CH'))
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/en-US'))
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/fr-BE'))
expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
'de-CH': {
common: {},
Expand All @@ -227,7 +227,7 @@ describe('serverSideTranslations', () => {
'namespace-of-fr-BE': {},
},
})
expect(props._nextI18Next.ns).toEqual([
expect(props._nextI18Next?.ns).toEqual([
'common',
'namespace-of-de-CH',
'namespace-of-en-US',
Expand All @@ -248,7 +248,7 @@ describe('serverSideTranslations', () => {
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/de'))
expect(fs.readdirSync).toHaveBeenCalledWith(expect.stringMatching('/public/locales/en'))

expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
'de-CH': {
common: {},
Expand All @@ -262,7 +262,7 @@ describe('serverSideTranslations', () => {
},
})

expect(props._nextI18Next.ns).toEqual([
expect(props._nextI18Next?.ns).toEqual([
'common',
'namespace-of-de-CH',
'namespace-of-en-US',
Expand All @@ -279,7 +279,7 @@ describe('serverSideTranslations', () => {
},
} as UserConfig, false)

expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
de: {
common: {},
Expand All @@ -289,7 +289,7 @@ describe('serverSideTranslations', () => {
},
})

expect(props._nextI18Next.ns).toEqual([
expect(props._nextI18Next?.ns).toEqual([
'common',
])
})
Expand All @@ -303,7 +303,7 @@ describe('serverSideTranslations', () => {
},
} as UserConfig, false)

expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
en: {
common: {},
Expand All @@ -313,7 +313,7 @@ describe('serverSideTranslations', () => {
},
})

expect(props._nextI18Next.ns).toEqual([
expect(props._nextI18Next?.ns).toEqual([
'common',
])
})
Expand All @@ -327,7 +327,7 @@ describe('serverSideTranslations', () => {
},
} as UserConfig, false)

expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
en: {
common: {},
Expand All @@ -337,7 +337,7 @@ describe('serverSideTranslations', () => {
},
})

expect(props._nextI18Next.ns).toEqual([
expect(props._nextI18Next?.ns).toEqual([
'common',
])
})
Expand All @@ -353,7 +353,7 @@ describe('serverSideTranslations', () => {
nonExplicitSupportedLngs: true,
} as UserConfig, false)

expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
de: {
common: {},
Expand All @@ -377,7 +377,7 @@ describe('serverSideTranslations', () => {
nonExplicitSupportedLngs: true,
} as UserConfig, false)

expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
en: {
common: {},
Expand All @@ -404,7 +404,7 @@ describe('serverSideTranslations', () => {
nonExplicitSupportedLngs: true,
} as UserConfig, false)

expect(props._nextI18Next.initialI18nStore)
expect(props._nextI18Next?.initialI18nStore)
.toEqual({
de: {
common: {},
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type UserConfig = {
i18n: NextJsI18NConfig
localeExtension?: string
localePath?:
string | ((locale: string, namespace: string, missing: boolean) => string)
string | ((locale: string, namespace: string, missing: boolean) => string)
localeStructure?: string
onPreInitI18next?: (i18n: I18n) => void
reloadOnPrerender?: boolean
Expand All @@ -48,7 +48,7 @@ export type CreateClientReturn = {
}

export type SSRConfig = {
_nextI18Next: {
_nextI18Next?: {
initialI18nStore: any
initialLocale: string
ns: string[]
Expand Down

0 comments on commit 73de76d

Please sign in to comment.