Skip to content

Commit

Permalink
feat(i18n): add types for translation keys
Browse files Browse the repository at this point in the history
  • Loading branch information
hatemhosny committed Apr 11, 2024
1 parent 4d3c04b commit d44159e
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 46 deletions.
8 changes: 4 additions & 4 deletions src/livecodes/i18n/locales/ar/language-info.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { I18nTranslation } from "../template";
import type { I18nTranslation } from '../models';

const languageInfo: I18nTranslation = {
artTemplateDesc: {
textContent: ""
}
artTemplateDesc: {
textContent: '',
},
};

export default languageInfo;
6 changes: 2 additions & 4 deletions src/livecodes/i18n/locales/ar/translation.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import type { I18nTranslation } from "../template";
import type { I18nTranslation } from '../models';

const translation: I18nTranslation = {
welcome: {
textContent: "مرحبا"
}
welcome: 'مرحبا',
};

export default translation;
15 changes: 9 additions & 6 deletions src/livecodes/i18n/locales/en/language-info.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { I18nTranslation } from "../template";
import { type I18nTranslationTemplate } from '../models';

const languageInfo: I18nTranslation = {
artTemplateDesc: {
textContent: "High performance JavaScript templating engine."
}
};
// This is used as a template for other translations.
// Other translations should be typed like this:
// const languageInfo: I18nTranslation = { /* translation here */ };
const languageInfo = {
artTemplateDesc: {
textContent: 'High performance JavaScript templating engine.',
},
} as const satisfies I18nTranslationTemplate;

export default languageInfo;
13 changes: 7 additions & 6 deletions src/livecodes/i18n/locales/en/translation.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { I18nTranslation } from "../template";
import { type I18nTranslationTemplate } from '../models';

const translation: I18nTranslation = {
welcome: {
textContent: "Welcome"
}
};
// This is used as a template for other translations.
// Other translations should be typed like this:
// const translation: I18nTranslation = { /* translation here */ };
const translation = {
welcome: 'Welcome',
} as const satisfies I18nTranslationTemplate;

export default translation;
31 changes: 31 additions & 0 deletions src/livecodes/i18n/locales/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-disable import/no-internal-modules */
import type translation from './en/translation';
import type LangInfoTranslation from './en/language-info';

// Report error when no property is provided
type RequireAtLeastOne<T> = {
[K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;
}[keyof T];

type I18nAttributes = RequireAtLeastOne<{
textContent?: string;
innerHTML?: string;
title?: string;
'data-hint'?: string;
}>;

export interface I18nTranslationTemplate {
[key: string]: I18nAttributes | string;
}

export type I18nTranslation = RequireAtLeastOne<
{
[key in keyof typeof translation]: (typeof translation)[key] extends I18nAttributes
? I18nAttributes
: string;
} & {
[key in keyof typeof LangInfoTranslation]: (typeof LangInfoTranslation)[key] extends I18nAttributes
? I18nAttributes
: string;
}
>;
15 changes: 0 additions & 15 deletions src/livecodes/i18n/locales/template.ts

This file was deleted.

8 changes: 4 additions & 4 deletions src/livecodes/i18n/locales/zh-CN/language-info.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { I18nTranslation } from "../template";
import type { I18nTranslation } from '../models';

const languageInfo: I18nTranslation = {
artTemplateDesc: {
textContent: "高性能 JavaScript 模板引擎。"
}
artTemplateDesc: {
textContent: '高性能 JavaScript 模板引擎。',
},
};

export default languageInfo;
6 changes: 2 additions & 4 deletions src/livecodes/i18n/locales/zh-CN/translation.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import type { I18nTranslation } from "../template";
import type { I18nTranslation } from '../models';

const translation: I18nTranslation = {
welcome: {
textContent: "欢迎"
}
welcome: '欢迎',
};

export default translation;
8 changes: 5 additions & 3 deletions src/livecodes/i18n/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ export const translate = (
if (!key) return;
const props = (el.dataset.i18nProp || 'textContent').split(' ');
props.forEach((prop) => {
if (prop.startsWith("data-")) {
const isObject = typeof i18n.t(key, { returnObjects: true }) === 'object';
const lookupKey = isObject ? `${key}.${prop}` : key;
if (prop.startsWith('data-')) {
prop = prop.slice(5);
el.dataset[prop] = i18n.t(`${key}.${prop}`, el.dataset[prop]!);
el.dataset[prop] = i18n.t(lookupKey, el.dataset[prop]!);
} else {
(el as any)[prop] = i18n.t(`${key}.${prop}`, (el as any)[prop]);
(el as any)[prop] = i18n.t(lookupKey, (el as any)[prop]);
}
});
});
Expand Down

0 comments on commit d44159e

Please sign in to comment.