MST

星途 面试题库

面试题:复杂场景下TypeScript类型守卫的设计与优化

假设你正在开发一个复杂的前端应用,有一个对象,其结构可能非常复杂且不确定。例如,对象可能包含嵌套对象、数组,内部元素类型多样。设计一套完善的TypeScript类型守卫机制,确保在访问对象深层属性时,能够安全地获取到期望类型的值,并且要考虑性能优化,避免不必要的类型检查。描述你的设计思路并给出关键代码示例。
41.9万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 类型守卫函数:针对不同的数据类型(对象、数组等)编写类型守卫函数,用于判断某个值是否具有特定的结构。
  2. 递归检查:由于对象可能嵌套,需要递归地应用类型守卫函数来处理深层结构。
  3. 缓存结果:为了避免不必要的类型检查,可以缓存类型检查的结果,尤其是对于频繁访问的属性。

关键代码示例

// 类型守卫函数,判断是否为对象
function isObject(value: any): value is Record<string, any> {
    return typeof value === 'object' && value!== null;
}

// 类型守卫函数,判断是否为数组
function isArray<T>(value: any): value is T[] {
    return Array.isArray(value);
}

// 安全获取对象深层属性的函数
function safeGet<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(
    obj: T,
    key1: K1,
    key2: K2,
    key3: K3
): T[K1][K2][K3] | undefined {
    if (isObject(obj) && key1 in obj) {
        const subObj = obj[key1];
        if (isObject(subObj) && key2 in subObj) {
            const subSubObj = subObj[key2];
            if (isObject(subSubObj) && key3 in subSubObj) {
                return subSubObj[key3];
            }
        }
    }
    return undefined;
}

// 示例对象
const complexObj = {
    a: {
        b: {
            c: 123
        }
    }
};

// 使用安全获取函数
const result = safeGet(complexObj, 'a', 'b', 'c');
if (result!== undefined) {
    console.log(result); // 输出: 123
}

性能优化

  1. 缓存机制:可以使用WeakMap来缓存类型检查的结果,因为WeakMap的键是弱引用,不会阻止对象被垃圾回收。
const typeCheckCache = new WeakMap<any, boolean>();

function isObjectCached(value: any): value is Record<string, any> {
    if (typeCheckCache.has(value)) {
        return typeCheckCache.get(value)!;
    }
    const result = typeof value === 'object' && value!== null;
    typeCheckCache.set(value, result);
    return result;
}
  1. 减少不必要的递归:在递归检查时,可以根据具体业务需求,提前返回结果,避免对深层结构进行不必要的检查。例如,如果已知某个属性不存在,就不需要继续深入检查。