diff --git a/__tests__/useTranslation.test.js b/__tests__/useTranslation.test.js
index 5c6c05e1..e2466d5e 100644
--- a/__tests__/useTranslation.test.js
+++ b/__tests__/useTranslation.test.js
@@ -1170,6 +1170,58 @@ describe('useTranslation', () => {
const expected = 'This is a default translation with a count: 3'
+ const { container } = render(
+
+
+
+ )
+ expect(container.textContent).toBe(expected)
+ })
+ test('should allow default object translation with interpolation', () => {
+ const Inner = () => {
+ const { t } = useTranslation()
+ const text = t(
+ 'ns:no-translation',
+ { count: 3 },
+ {
+ default: {
+ example: 'This is a default translation with a count: {{count}}'
+ },
+ returnObjects: true,
+ fallback: 'ns:no-translation2',
+ }
+ )
+ return <>{text.example}>
+ }
+
+ const expected = 'This is a default translation with a count: 3'
+
+ const { container } = render(
+
+
+
+ )
+ expect(container.textContent).toBe(expected)
+ })
+ test('should allow default array translation with interpolation', () => {
+ const Inner = () => {
+ const { t } = useTranslation()
+ const text = t(
+ 'ns:no-translation',
+ { count: 3 },
+ {
+ default: [
+ 'This is a default translation with a count: {{count}}'
+ ],
+ returnObjects: true,
+ fallback: 'ns:no-translation2',
+ }
+ )
+ return <>{text[0]}>
+ }
+
+ const expected = 'This is a default translation with a count: 3'
+
const { container } = render(
diff --git a/src/Trans.tsx b/src/Trans.tsx
index 893c763f..21be3c50 100644
--- a/src/Trans.tsx
+++ b/src/Trans.tsx
@@ -23,7 +23,7 @@ export default function Trans({
* Memoize the transformation
*/
const result = useMemo(() => {
- const text = t(i18nKey, values, { fallback, default: defaultTrans })
+ const text = t(i18nKey, values, { fallback, default: defaultTrans })
if (!components || components.length === 0) return text
diff --git a/src/index.tsx b/src/index.tsx
index a8116b28..efcf0311 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -5,13 +5,22 @@ export interface TranslationQuery {
[name: string]: any
}
-export type Translate = (
+
+export interface NestedStringObject {
+ [key:string]: string | NestedStringObject | NestedStringArray
+}
+type ValueOrArray = T | ValueOrArray[];
+type NestedStringArray = ValueOrArray;
+
+export type TranslateValue = string | NestedStringObject | NestedStringArray
+
+export type Translate = (
i18nKey: string | TemplateStringsArray,
query?: TranslationQuery | null,
options?: {
returnObjects?: boolean
fallback?: string | string[]
- default?: string
+ default?: T | string
ns?: string
}
) => T
diff --git a/src/transCore.tsx b/src/transCore.tsx
index 8ff3a308..0d7ac290 100644
--- a/src/transCore.tsx
+++ b/src/transCore.tsx
@@ -3,6 +3,7 @@ import {
I18nDictionary,
LoaderConfig,
LoggerProps,
+ TranslateValue,
TranslationQuery,
} from '.'
import { Translate } from './index'
@@ -37,6 +38,21 @@ export default function transCore({
allowEmptyStrings = true,
} = config
+ const interpolateUnknown = (value: TranslateValue, query?: TranslationQuery | null): TranslateValue => {
+ if (Array.isArray(value)) {
+ return value.map(val => interpolateUnknown(val, query));
+ }
+ if (value instanceof Object) {
+ return objectInterpolation({
+ obj: value as Record,
+ query,
+ config,
+ lang,
+ })
+ }
+ return interpolation({ text: value as string, query, config, lang })
+ }
+
const t: Translate = (key = '', query, options) => {
const k = Array.isArray(key) ? key[0] : key
const { nsSeparator = ':', loggerEnvironment = 'browser' } = config
@@ -81,8 +97,8 @@ export default function transCore({
}
}
- if (empty && options?.default && fallbacks?.length == 0) {
- return interpolation({ text: options?.default, query, config, lang })
+ if (empty && options?.default && !fallbacks?.length) {
+ return interpolateUnknown(options.default, query)
}
// no need to try interpolation
@@ -90,18 +106,9 @@ export default function transCore({
return k
}
- if (value instanceof Object) {
- return objectInterpolation({
- obj: value as Record,
- query,
- config,
- lang,
- })
- }
-
// this can return an empty string if either value was already empty
// or it contained only an interpolation (e.g. "{{name}}") and the query param was empty
- return interpolation({ text: value as string, query, config, lang })
+ return interpolateUnknown(value, query)
}
return t
@@ -117,7 +124,7 @@ function getDicValue(
options: { returnObjects?: boolean; fallback?: string | string[] } = {
returnObjects: false,
}
-): string | undefined | object {
+): TranslateValue | undefined {
const { keySeparator = '.' } = config || {}
const keyParts = keySeparator ? key.split(keySeparator) : [key]
@@ -141,7 +148,7 @@ function getDicValue(
typeof value === 'string' ||
((value as unknown) instanceof Object && options.returnObjects)
) {
- return value
+ return value as TranslateValue
}
return undefined
@@ -203,8 +210,6 @@ function interpolation({
const regexEnd =
suffix === '' ? '' : `(?:[\\s,]+([\\w-]*))?\\s*${escapeRegex(suffix)}`
return Object.keys(query).reduce((all, varKey) => {
- if (typeof all !== 'string') return all
-
const regex = new RegExp(
`${escapeRegex(prefix)}\\s*${varKey}${regexEnd}`,
'gm'
@@ -232,7 +237,6 @@ function objectInterpolation({
lang?: string
}): any {
if (!query || Object.keys(query).length === 0) return obj
-
Object.keys(obj).forEach((key) => {
if (obj[key] instanceof Object)
objectInterpolation({
diff --git a/yarn.lock b/yarn.lock
index 015edc2b..4db9041a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5537,4 +5537,4 @@ yargs@^16.2.0:
require-directory "^2.1.1"
string-width "^4.2.0"
y18n "^5.0.5"
- yargs-parser "^20.2.2"
+ yargs-parser "^20.2.2"
\ No newline at end of file