MST

星途 面试题库

面试题:TypeScript 函数类型注解与接口在大型前端项目架构中的优化

在一个大型的前端单页应用(SPA)项目中,涉及到用户认证、权限管理、多语言切换等多个复杂模块。各个模块之间通过函数进行数据交互和功能调用。请阐述如何运用 TypeScript 的函数类型注解与接口来优化项目架构,提高代码的可维护性、可扩展性和健壮性。要求结合实际项目经验,从模块划分、接口设计、函数契约等方面详细说明。
33.3万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

模块划分

  1. 按功能划分模块:例如将用户认证相关的代码放在 auth 模块,权限管理放在 permission 模块,多语言切换放在 i18n 模块。这样每个模块职责明确,在 TypeScript 中,每个模块可以有自己的接口和函数定义。
    • auth 模块为例,创建 auth.ts 文件,在其中定义与用户认证相关的接口和函数。
  2. 模块间依赖管理:使用 TypeScript 模块系统,明确导入和导出。比如 permission 模块可能依赖 auth 模块的用户信息,通过 import { userInfo } from './auth'; 进行导入,确保模块间依赖关系清晰。

接口设计

  1. 用户认证接口
    • 定义登录接口,例如:
interface LoginRequest {
    username: string;
    password: string;
}

interface LoginResponse {
    token: string;
    userInfo: {
        id: number;
        name: string;
    };
}
- 这样在登录函数中,参数和返回值类型明确,如:
async function login(credentials: LoginRequest): Promise<LoginResponse> {
    // 实际登录逻辑,这里模拟返回数据
    return {
        token: 'exampleToken',
        userInfo: {
            id: 1,
            name: 'John Doe'
        }
    };
}
  1. 权限管理接口
    • 定义权限数据接口:
interface Permission {
    permissionId: string;
    name: string;
    description: string;
}

interface UserPermissions {
    userId: number;
    permissions: Permission[];
}
- 例如获取用户权限的函数:
async function getPermissions(userId: number): Promise<UserPermissions> {
    // 实际获取权限逻辑,模拟返回数据
    return {
        userId,
        permissions: [
            {
                permissionId: 'p1',
                name: 'viewDashboard',
                description: 'Can view the dashboard'
            }
        ]
    };
}
  1. 多语言切换接口
    • 定义语言包接口:
interface LanguagePack {
    [key: string]: string;
}

interface LanguageConfig {
    languageCode: string;
    pack: LanguagePack;
}
- 例如加载语言包的函数:
async function loadLanguage(langCode: string): Promise<LanguageConfig> {
    // 实际加载语言包逻辑,模拟返回数据
    return {
        languageCode: langCode,
        pack: {
            'welcome': 'Welcome'
        }
    };
}

函数契约

  1. 明确函数参数和返回值类型:通过函数类型注解,确保调用者传递正确类型的参数,并且知道函数返回值的类型。例如在用户认证模块中,login 函数接受 LoginRequest 类型参数,返回 LoginResponse 类型数据。这避免了运行时因参数类型错误导致的问题,提高代码健壮性。
  2. 错误处理契约:在函数注解中可以通过 Promise<ReturnType | ErrorType> 方式来表示可能返回的错误类型。例如,在 login 函数中,如果登录失败,可以返回一个包含错误信息的对象,函数定义可改为:
async function login(credentials: LoginRequest): Promise<LoginResponse | { error: string }> {
    // 实际登录逻辑,这里模拟登录失败情况
    if (credentials.username === 'errorUser') {
        return { error: 'Invalid username or password' };
    }
    return {
        token: 'exampleToken',
        userInfo: {
            id: 1,
            name: 'John Doe'
        }
    };
}
  1. 函数间调用契约:由于模块间通过函数交互,明确的函数类型注解使得模块间调用更加可靠。例如 permission 模块中判断用户是否有权限的函数可能依赖 auth 模块获取的用户信息,通过接口和函数类型注解保证了这种依赖关系的正确性和稳定性,提高代码的可维护性和可扩展性。