MST

星途 面试题库

面试题:TypeScript 国际化方案在复杂场景下的类型安全设计

假设我们的项目是一个支持多语言、多租户且具有复杂权限管理的企业级应用。每个租户可能有自己定制的国际化文本,并且不同权限的用户看到的某些翻译文本也会不同。请设计一个基于TypeScript的国际化方案,全面考虑类型安全,包括但不限于定义合适的类型来表示租户、权限与国际化文本之间的关系,以及如何在各种复杂操作(如权限变更、租户切换等)下保持类型的一致性和安全性。
46.8万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
  1. 定义基础类型
    • 首先定义租户类型:
    type TenantId = string;
    type Tenant = {
        id: TenantId;
        // 其他租户相关属性
    };
    
    • 然后定义权限类型:
    type Permission = string;
    type UserPermissions = Permission[];
    
  2. 定义国际化文本类型
    • 对于国际化文本,我们可以这样定义:
    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;
        };
    };
    
  3. 创建国际化服务
    • 我们可以创建一个国际化服务类来管理这些操作:
    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;
        }
    }
    
  4. 处理权限变更和租户切换
    • 权限变更
      • 当权限变更时,例如用户权限增加或减少,我们只需要调用 setPermissionTranslations 方法更新权限相关的翻译文本。由于我们在类型定义中明确了权限和翻译文本的关系,所以在调用这些方法时,TypeScript 会确保类型安全。
    • 租户切换
      • 当租户切换时,我们需要更新当前使用的租户 ID。在获取翻译文本时,会根据新的租户 ID 从 tenantTranslations 中获取相应的翻译。同样,由于类型定义明确,在进行租户切换相关操作时,TypeScript 可以保证类型的一致性和安全性。

通过以上方案,我们在 TypeScript 中设计了一个满足多语言、多租户且复杂权限管理的国际化方案,同时保证了类型安全。