MST
星途 面试题库

面试题:TypeScript函数在复杂业务场景下的类型设计

假设你正在开发一个前端数据处理模块,有一个函数需要处理不同来源的数据(可能是从API获取的JSON数据,也可能是本地缓存数据,且数据结构会根据业务需求动态变化)。请设计一个TypeScript函数,该函数接受一个表示数据来源的字符串参数(如'api'或'cache')和相应的数据对象,根据数据来源进行不同的数据预处理操作(如API数据可能需要解密,缓存数据可能需要解压缩),并最终返回处理后的数据。要求对函数的参数、返回值进行精确的类型定义,使用类型守卫和交叉类型等高级特性确保类型安全,同时说明在设计过程中如何应对数据结构动态变化的问题。
11.9万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
// 定义API数据的类型
type ApiData = {
    encryptedData: string;
    // 这里可以根据实际API数据结构添加更多属性
};

// 定义缓存数据的类型
type CacheData = {
    compressedData: string;
    // 这里可以根据实际缓存数据结构添加更多属性
};

// 定义处理后的数据的通用类型
type ProcessedData = {
    // 这里定义处理后的数据的通用属性
    processed: boolean;
};

// 定义类型守卫函数来判断数据来源
function isApiData(data: ApiData | CacheData): data is ApiData {
    return 'encryptedData' in data;
}

// 定义数据处理函数
function processData(source: 'api' | 'cache', data: ApiData | CacheData): ProcessedData {
    let processedData: ProcessedData;
    if (source === 'api') {
        if (isApiData(data)) {
            // 模拟API数据解密操作
            const decryptedData = decrypt(data.encryptedData);
            processedData = { processed: true };
            // 可以在这里对解密后的数据进行更多处理
        } else {
            throw new Error('Invalid data source for API processing');
        }
    } else {
        if (!isApiData(data)) {
            // 模拟缓存数据解压缩操作
            const decompressedData = decompress(data.compressedData);
            processedData = { processed: true };
            // 可以在这里对解压缩后的数据进行更多处理
        } else {
            throw new Error('Invalid data source for cache processing');
        }
    }
    return processedData;
}

// 模拟解密函数
function decrypt(data: string): string {
    // 实际解密逻辑
    return data;
}

// 模拟解压缩函数
function decompress(data: string): string {
    // 实际解压缩逻辑
    return data;
}

应对数据结构动态变化的问题

  1. 使用类型别名和交叉类型:定义不同来源数据的类型别名(如ApiDataCacheData),如果数据结构有部分通用的属性,可以使用交叉类型来合并类型,这样在类型层面可以灵活应对数据结构的动态变化。
  2. 类型守卫:通过类型守卫函数(如isApiData),在运行时判断数据的实际类型,从而可以针对不同类型的数据进行安全的操作,避免类型错误。
  3. 动态属性访问:如果数据结构中有一些动态变化的属性,可以使用索引类型来处理,例如data[key: string],这样在访问属性时可以动态根据实际情况获取或设置属性值。同时结合类型断言,在确保类型安全的前提下访问动态属性。