diff --git a/src/dev/i18n_tools/__fixtures__/extraction_signatures/template_literal_var.ts b/src/dev/i18n_tools/__fixtures__/extraction_signatures/template_literal_var.ts new file mode 100644 index 0000000000000..1c482370ad725 --- /dev/null +++ b/src/dev/i18n_tools/__fixtures__/extraction_signatures/template_literal_var.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { i18n } from '@kbn/i18n'; + +const e = new Error('Should not work'); + +i18n.translate('contains_variable', { + defaultMessage: `value passed into literal directly (e: ${e.message})`, +}); + +i18n.translate('no_variable', { + defaultMessage: `template literal without any variable expressions (e: {errorMessage})`, + values: { errorMessage: e.message }, +}); diff --git a/src/dev/i18n_tools/extractors/call_expt.ts b/src/dev/i18n_tools/extractors/call_expt.ts index 3677b71fb2bb5..df3d05dc6b73e 100644 --- a/src/dev/i18n_tools/extractors/call_expt.ts +++ b/src/dev/i18n_tools/extractors/call_expt.ts @@ -286,6 +286,15 @@ export function extractMessageDescriptor( break; } } + } else if (typescript.isTemplateExpression(initializer)) { + initializer.forEachChild((child) => { + if (typescript.isTemplateSpan(child)) { + const messageText = initializer.getFullText(); + throw new Error( + `Template literals with variable substitution is not supported. please pass variables via the 'values' object instead. Message ${messageText}` + ); + } + }); } // {id: `id`} else if (typescript.isNoSubstitutionTemplateLiteral(initializer)) { diff --git a/src/dev/i18n_tools/extractors/formatjs.test.ts b/src/dev/i18n_tools/extractors/formatjs.test.ts index 85c1642519e80..3df36c0c7447b 100644 --- a/src/dev/i18n_tools/extractors/formatjs.test.ts +++ b/src/dev/i18n_tools/extractors/formatjs.test.ts @@ -267,6 +267,14 @@ describe('formatJS Runner', () => { } `); }); + + it('throws when template literal has a variable', async () => { + await expect(async () => + formatJsFixtureRunner('template_literal_var.ts') + ).rejects.toMatchInlineSnapshot( + `[Error: Error parsing file template_literal_var.ts: Error: Template literals with variable substitution is not supported. please pass variables via the 'values' object instead. Message \`value passed into literal directly (e: \${e.message})\`]` + ); + }); }); describe('extraction inside react components', () => {