面试题答案
一键面试- 定义基础类型
- 首先定义租户类型:
type TenantId = string; type Tenant = { id: TenantId; // 其他租户相关属性 };
- 然后定义权限类型:
type Permission = string; type UserPermissions = Permission[];
- 定义国际化文本类型
- 对于国际化文本,我们可以这样定义:
type Locale = string; type Translations = { [key: string]: string; }; type TenantTranslations = { [tenantId in TenantId]: { [locale in Locale]: Translations; }; }; type PermissionTranslations = { [permission in Permission]: { [locale in Locale]: Translations; }; };
- 创建国际化服务
- 我们可以创建一个国际化服务类来管理这些操作:
class I18nService { private tenantTranslations: TenantTranslations = {}; private permissionTranslations: PermissionTranslations = {}; constructor() {} // 方法:设置租户的翻译文本 public setTenantTranslations(tenantId: TenantId, locale: Locale, translations: Translations) { if (!this.tenantTranslations[tenantId]) { this.tenantTranslations[tenantId] = {}; } this.tenantTranslations[tenantId][locale] = translations; } // 方法:设置权限相关的翻译文本 public setPermissionTranslations(permission: Permission, locale: Locale, translations: Translations) { if (!this.permissionTranslations[permission]) { this.permissionTranslations[permission] = {}; } this.permissionTranslations[permission][locale] = translations; } // 方法:获取翻译文本,考虑租户和权限 public getTranslation(tenantId: TenantId, userPermissions: UserPermissions, locale: Locale, key: string): string { let translation = ''; // 先尝试从租户特定翻译中获取 if (this.tenantTranslations[tenantId] && this.tenantTranslations[tenantId][locale]) { translation = this.tenantTranslations[tenantId][locale][key] || ''; } // 如果租户特定翻译中没有,尝试从权限相关翻译中获取 if (!translation) { userPermissions.forEach(permission => { if (this.permissionTranslations[permission] && this.permissionTranslations[permission][locale]) { translation = this.permissionTranslations[permission][locale][key] || translation; } }); } return translation; } }
- 处理权限变更和租户切换
- 权限变更:
- 当权限变更时,例如用户权限增加或减少,我们只需要调用
setPermissionTranslations
方法更新权限相关的翻译文本。由于我们在类型定义中明确了权限和翻译文本的关系,所以在调用这些方法时,TypeScript 会确保类型安全。
- 当权限变更时,例如用户权限增加或减少,我们只需要调用
- 租户切换:
- 当租户切换时,我们需要更新当前使用的租户 ID。在获取翻译文本时,会根据新的租户 ID 从
tenantTranslations
中获取相应的翻译。同样,由于类型定义明确,在进行租户切换相关操作时,TypeScript 可以保证类型的一致性和安全性。
- 当租户切换时,我们需要更新当前使用的租户 ID。在获取翻译文本时,会根据新的租户 ID 从
- 权限变更:
通过以上方案,我们在 TypeScript 中设计了一个满足多语言、多租户且复杂权限管理的国际化方案,同时保证了类型安全。