diff --git a/src/utils/typescript.ts b/src/utils/typescript.ts index 9f81c9eb..f2763472 100644 --- a/src/utils/typescript.ts +++ b/src/utils/typescript.ts @@ -1,5 +1,20 @@ import * as ts from 'typescript'; +const convertArrayItemToType = async (item: any): Promise => { + if (Array.isArray(item)) { + const nestedArrayItemTypes = await Promise.all( + item.map((nestedItem) => convertArrayItemToType(nestedItem)), + ); + return ts.factory.createTupleTypeNode(nestedArrayItemTypes); + } + if (typeof item === 'object') { + return ts.factory.createTypeLiteralNode( + await convertObjectToTypeDefinition(item), + ); + } + return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword); +}; + export const convertObjectToTypeDefinition = async ( object: any, ): Promise => { @@ -7,7 +22,9 @@ export const convertObjectToTypeDefinition = async ( case 'object': return Promise.all( Object.keys(object).map(async (key) => { - if (typeof object[key] === 'string') { + const value = object[key]; + + if (typeof value === 'string') { return ts.factory.createPropertySignature( undefined, ts.factory.createStringLiteral(key), @@ -15,16 +32,15 @@ export const convertObjectToTypeDefinition = async ( ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), ); } - if (Array.isArray(object[key])) { + if (Array.isArray(value)) { + const arrayItemTypes = await Promise.all( + value.map((item) => convertArrayItemToType(item)), + ); return ts.factory.createPropertySignature( undefined, ts.factory.createStringLiteral(key), undefined, - ts.factory.createTupleTypeNode( - Array(object[key].length).fill( - ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), - ), - ), + ts.factory.createTupleTypeNode(arrayItemTypes), ); } return ts.factory.createPropertySignature( @@ -32,7 +48,7 @@ export const convertObjectToTypeDefinition = async ( ts.factory.createStringLiteral(key), undefined, ts.factory.createTypeLiteralNode( - await convertObjectToTypeDefinition(object[key]), + await convertObjectToTypeDefinition(value), ), ); }), diff --git a/tests/generated/i18n.generated.ts b/tests/generated/i18n.generated.ts index e5955ec4..484833e5 100644 --- a/tests/generated/i18n.generated.ts +++ b/tests/generated/i18n.generated.ts @@ -17,6 +17,20 @@ export type I18nTranslations = { string, string ]; + "OBJECTS_ARRAY": [ + { + "instructions": string; + }, + { + "nestedArrayInstructions": [ + [ + { + "instructions": string; + } + ] + ]; + } + ]; "cat": string; "ONLY_EN_KEY": string; "cat_name": string; diff --git a/tests/i18n.spec.ts b/tests/i18n.spec.ts index dfee2c46..49c0f7fe 100644 --- a/tests/i18n.spec.ts +++ b/tests/i18n.spec.ts @@ -76,6 +76,36 @@ describe('i18n module', () => { expect(i18nService.translate('test.ARRAY.2', { lang: 'nl' })).toBe('DRIE'); }); + it('i18n service should return objects array translation', () => { + expect( + i18nService.translate('test.OBJECTS_ARRAY.0.instructions', { + lang: 'en', + }), + ).toBe('Please follow the link'); + expect( + i18nService.translate( + 'test.OBJECTS_ARRAY.1.nestedArrayInstructions.0.0.instructions', + { + lang: 'en', + }, + ), + ).toBe('Please try again'); + + expect( + i18nService.translate('test.OBJECTS_ARRAY.0.instructions', { + lang: 'uk', + }), + ).toBe('Будь ласка, перейдіть за посиланням'); + expect( + i18nService.translate( + 'test.OBJECTS_ARRAY.1.nestedArrayInstructions.0.0.instructions', + { + lang: 'uk', + }, + ), + ).toBe('Будь ласка, спробуйте ще раз'); + }); + it('i18n service should return fallback translation', () => { expect(i18nService.translate('test.ENGLISH', { lang: 'nl' })).toBe( 'English', diff --git a/tests/i18n/en/test.json b/tests/i18n/en/test.json index ef7e0102..69a1253c 100644 --- a/tests/i18n/en/test.json +++ b/tests/i18n/en/test.json @@ -5,6 +5,12 @@ }, "ENGLISH": "English", "ARRAY": ["ONE", "TWO", "THREE"], + "OBJECTS_ARRAY": [ + { "instructions": "Please follow the link" }, + { + "nestedArrayInstructions": [[{ "instructions": "Please try again" }]] + } + ], "cat": "Cat", "ONLY_EN_KEY": "this key only exists in en lang", "cat_name": "Cat: {name}", diff --git a/tests/i18n/uk/test.json b/tests/i18n/uk/test.json index 3fab07f2..98bf1bfb 100644 --- a/tests/i18n/uk/test.json +++ b/tests/i18n/uk/test.json @@ -1,4 +1,12 @@ { + "OBJECTS_ARRAY": [ + { "instructions": "Будь ласка, перейдіть за посиланням" }, + { + "nestedArrayInstructions": [ + [{ "instructions": "Будь ласка, спробуйте ще раз" }] + ] + } + ], "day_interval": { "one": "{count} день", "few": "{count} дні",