🦄 refactor(i18n): replace manual types with auto-inference

- Migrate from manual TypeScript interfaces to automatic type generation
from JSON files. Eliminates sync issues and maintenance overhead.
This commit is contained in:
IGCrystal
2025-06-17 11:10:21 +08:00
parent 8275130f04
commit 7e4c89b0cb
2 changed files with 35 additions and 269 deletions
+13 -1
View File
@@ -197,6 +197,7 @@ export class I18nLoader {
*/
private mergeModules(modules: any[], moduleNames: string[]): any {
const result: any = {};
const pathRegistry = new Map<string, string>();
modules.forEach((module, index) => {
const moduleName = moduleNames[index];
@@ -211,8 +212,19 @@ export class I18nLoader {
current = current[nameParts[i]];
}
// 设置最终值
// 冲突检测:检查最终键是否已存在
const finalKey = nameParts[nameParts.length - 1];
const fullPath = nameParts.join('.');
if (current[finalKey] && pathRegistry.has(fullPath)) {
const existingModule = pathRegistry.get(fullPath);
console.warn(`⚠️ I18n模块路径冲突: "${fullPath}" 已被模块 "${existingModule}" 占用,模块 "${moduleName}" 可能会覆盖部分键值`);
}
// 记录路径和模块名的映射
pathRegistry.set(fullPath, moduleName);
// 设置最终值(保持原有的浅合并行为)
current[finalKey] = { ...current[finalKey], ...module };
});
+22 -268
View File
@@ -1,279 +1,31 @@
/**
* I18n TypeScript Type Definitions
* 国际化类型定义,确保类型安全
* I18n TypeScript Type Definitions - Auto-generated from JSON
* 国际化类型定义,从JSON文件自动推断,确保类型安全且自动同步
*/
// 核心模块类型定义
export interface CoreTranslations {
common: {
save: string;
cancel: string;
close: string;
delete: string;
edit: string;
add: string;
confirm: string;
loading: string;
success: string;
error: string;
warning: string;
info: string;
name: string;
description: string;
author: string;
status: string;
actions: string;
enable: string;
disable: string;
enabled: string;
disabled: string;
reload: string;
configure: string;
install: string;
uninstall: string;
update: string;
language: string;
};
actions: {
create: string;
read: string;
update: string;
delete: string;
search: string;
filter: string;
sort: string;
export: string;
import: string;
backup: string;
restore: string;
};
status: {
loading: string;
success: string;
error: string;
warning: string;
info: string;
pending: string;
processing: string;
completed: string;
failed: string;
cancelled: string;
};
navigation: {
dashboard: string;
platforms: string;
providers: string;
toolUse: string;
config: string;
extension: string;
chat: string;
conversation: string;
console: string;
alkaid: string;
about: string;
settings: string;
documentation: string;
github: string;
drag: string;
};
}
// 直接导入已经组织好的翻译数据
import { translations } from './translations';
// 功能模块类型定义
export interface FeatureTranslations {
chat: {
title: string;
subtitle: string;
input: {
placeholder: string;
send: string;
clear: string;
};
message: {
user: string;
assistant: string;
system: string;
};
voice: {
start: string;
stop: string;
recording: string;
};
};
extension: {
title: string;
subtitle: string;
showSystemPlugins: string;
hideSystemPlugins: string;
platformCommandConfig: string;
noPlugins: string;
tryInstallOrShowSystem: string;
configDialog: {
title: string;
noConfig: string;
};
platformConfig: {
title: string;
description: string;
noPlatforms: string;
addPlatformFirst: string;
goToPlatformManagement: string;
};
marketplace: {
title: string;
installPlugin: string;
fromGitHub: string;
fromLocal: string;
repoUrl: string;
selectFile: string;
pluginDevelopmentDoc: string;
submitPluginRepo: string;
};
};
conversation: {
title: string;
subtitle: string;
table: {
id: string;
platform: string;
user: string;
message: string;
time: string;
actions: string;
};
filter: {
platform: string;
user: string;
dateRange: string;
};
export: {
title: string;
format: string;
range: string;
};
};
provider: {
title: string;
tabTypes: {
chat_completion: string;
speech_to_text: string;
text_to_speech: string;
embedding: string;
};
openaiDescription: string;
defaultDescription: string;
};
platform: {
title: string;
subtitle: string;
adapters: string;
addAdapter: string;
};
config: {
title: string;
subtitle: string;
sections: {
general: string;
advanced: string;
security: string;
};
};
console: {
title: string;
subtitle: string;
clear: string;
download: string;
};
about: {
title: string;
version: string;
author: string;
license: string;
repository: string;
};
alkaid: {
comingSoon: string;
knowledgeBase: {
title: string;
subtitle: string;
};
memory: {
title: string;
subtitle: string;
};
};
}
// 导出翻译数据常量,供类型推断使用
export const translationData = translations;
// 消息模块类型定义
export interface MessageTranslations {
errors: {
network: {
timeout: string;
connection: string;
server: string;
};
validation: {
required: string;
invalid: string;
tooLong: string;
tooShort: string;
};
auth: {
unauthorized: string;
forbidden: string;
tokenExpired: string;
};
};
success: {
save: {
completed: string;
config: string;
settings: string;
};
action: {
created: string;
updated: string;
deleted: string;
};
};
validation: {
required: string;
email: string;
url: string;
number: string;
min: string;
max: string;
};
}
// 从实际的翻译数据推断完整的翻译结构类型
export type TranslationSchema = typeof translations[keyof typeof translations];
// 完整的翻译类型
export interface TranslationSchema extends CoreTranslations, FeatureTranslations, MessageTranslations {}
// TypeScript 助手:递归提取嵌套键路径
type NestedKeyOf<T> = T extends object
? {
[K in keyof T & string]: T[K] extends object
? `${K}` | `${K}.${NestedKeyOf<T[K]>}`
: `${K}`
}[keyof T & string]
: never;
// 翻译键类型
export type TranslationKey =
// Core keys
| `core.common.${keyof CoreTranslations['common']}`
| `core.actions.${keyof CoreTranslations['actions']}`
| `core.status.${keyof CoreTranslations['status']}`
| `core.navigation.${keyof CoreTranslations['navigation']}`
// Feature keys
| `features.chat.${keyof FeatureTranslations['chat'] | `input.${keyof FeatureTranslations['chat']['input']}` | `message.${keyof FeatureTranslations['chat']['message']}` | `voice.${keyof FeatureTranslations['chat']['voice']}`}`
| `features.extension.${keyof FeatureTranslations['extension'] | `configDialog.${keyof FeatureTranslations['extension']['configDialog']}` | `platformConfig.${keyof FeatureTranslations['extension']['platformConfig']}` | `marketplace.${keyof FeatureTranslations['extension']['marketplace']}`}`
| `features.conversation.${keyof FeatureTranslations['conversation'] | `table.${keyof FeatureTranslations['conversation']['table']}` | `filter.${keyof FeatureTranslations['conversation']['filter']}` | `export.${keyof FeatureTranslations['conversation']['export']}`}`
| `features.provider.${keyof FeatureTranslations['provider'] | `tabTypes.${keyof FeatureTranslations['provider']['tabTypes']}`}`
| `features.platform.${keyof FeatureTranslations['platform']}`
| `features.config.${keyof FeatureTranslations['config'] | `sections.${keyof FeatureTranslations['config']['sections']}`}`
| `features.console.${keyof FeatureTranslations['console']}`
| `features.about.${keyof FeatureTranslations['about']}`
| `features.alkaid.${keyof FeatureTranslations['alkaid'] | `knowledgeBase.${keyof FeatureTranslations['alkaid']['knowledgeBase']}` | `memory.${keyof FeatureTranslations['alkaid']['memory']}`}`
// Message keys
| `messages.errors.${keyof MessageTranslations['errors'] | `network.${keyof MessageTranslations['errors']['network']}` | `validation.${keyof MessageTranslations['errors']['validation']}` | `auth.${keyof MessageTranslations['errors']['auth']}`}`
| `messages.success.${keyof MessageTranslations['success'] | `save.${keyof MessageTranslations['success']['save']}` | `action.${keyof MessageTranslations['success']['action']}`}`
| `messages.validation.${keyof MessageTranslations['validation']}`;
// 自动推断的翻译键联合类型 - 包含所有有效的点分隔键路径
export type TranslationKey = NestedKeyOf<TranslationSchema>;
// 语言环境类型
export type Locale = 'zh-CN' | 'en-US';
// 语言环境类型 - 从实际的翻译数据键推断
export type Locale = keyof typeof translations;
// 翻译函数类型
export type TranslationFunction = {
@@ -281,6 +33,8 @@ export type TranslationFunction = {
(key: TranslationKey, params: Record<string, string | number>): string;
};
// 以下是保留的工具类型定义,这些不依赖具体的翻译结构
// 模块加载状态
export interface ModuleLoadingState {
core: boolean;