Skip to content

Commit 141eb26

Browse files
committed
Add Internationalizable interface and type guard
1 parent 375ec18 commit 141eb26

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

packages/core/src/i18n/i18nUtil.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ErrorObject } from 'ajv';
2-
import { isControlElement, UISchemaElement } from '../models';
2+
import { isInternationalized, UISchemaElement } from '../models';
33
import { getControlPath } from '../reducers';
44
import { formatErrorMessage } from '../util';
55
import { i18nJsonSchema, ErrorTranslator, Translator } from './i18nTypes';
@@ -8,7 +8,7 @@ export const getI18nKeyPrefixBySchema = (
88
schema: i18nJsonSchema | undefined,
99
uischema: UISchemaElement | undefined
1010
): string | undefined => {
11-
if (uischema && isControlElement(uischema) && uischema.i18n) {
11+
if (isInternationalized(uischema)) {
1212
return uischema.i18n;
1313
}
1414
return schema?.i18n ?? undefined;

packages/core/src/models/uischema.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ export interface Scopable {
3636
scope: string;
3737
}
3838

39+
/**
40+
* Interface for describing an UI schema element that can provide an internationalization base key.
41+
* If defined, this key is suffixed to derive applicable message keys for the UI schema element.
42+
* For example, such suffixes are `.label` or `.description` to derive the corresponding message keys for a control element.
43+
*/
44+
export interface Internationalizable {
45+
i18n?: string;
46+
}
47+
3948
/**
4049
* A rule that may be attached to any UI schema element.
4150
*/
@@ -207,17 +216,12 @@ export interface LabelElement extends UISchemaElement {
207216
* A control element. The scope property of the control determines
208217
* to which part of the schema the control should be bound.
209218
*/
210-
export interface ControlElement extends UISchemaElement, Scopable {
219+
export interface ControlElement extends UISchemaElement, Scopable, Internationalizable {
211220
type: 'Control';
212221
/**
213222
* An optional label that will be associated with the control
214223
*/
215224
label?: string | boolean | LabelDescription;
216-
/**
217-
* The i18n key for the control. It is used to identify the string that needs to be translated.
218-
* It is suffixed with `.label`, `.description` and `.error.<keyword>` to derive the corresponding message keys for the control.
219-
*/
220-
i18n?: string;
221225
}
222226

223227
/**
@@ -249,8 +253,9 @@ export interface Categorization extends UISchemaElement {
249253
elements: (Category | Categorization)[];
250254
}
251255

252-
export const isControlElement = (element: UISchemaElement): element is ControlElement =>
253-
element.type === 'Control';
256+
export const isInternationalized = (element: unknown): element is Required<Internationalizable> => {
257+
return typeof element === 'object' && element !== null && typeof (element as Internationalizable).i18n === 'string';
258+
}
254259

255260
export const isGroup = (layout: Layout): layout is GroupLayout =>
256261
layout.type === 'Group';

0 commit comments

Comments
 (0)