MST
星途 面试题库

面试题:TypeScript泛型在复杂类型系统中的应用

假设你正在开发一个数据处理库,需要设计一系列使用泛型的工具函数,包括但不限于:一个可以对不同类型的对象数组进行深度过滤的函数,一个可以将对象数组按照某个属性进行分组的函数,并且这些函数要能正确处理嵌套对象和复杂数据结构。请给出实现思路,并编写关键部分的代码,同时说明如何确保类型安全和扩展性。
22.1万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 深度过滤函数
    • 遍历数组,对每个对象进行深度遍历,根据过滤条件判断是否保留该对象或对象中的属性。
    • 使用递归处理嵌套对象。
  2. 按属性分组函数
    • 遍历数组,根据指定属性的值创建分组,若属性值是对象,也需要处理嵌套情况。
    • 可以使用 Map 来存储分组结果。

关键部分代码

// 深度过滤函数
type FilterFunction<T> = (value: T, key: string | number | symbol, obj: T) => boolean;

function deepFilter<T>(arr: T[], filterFn: FilterFunction<T>): T[] {
    return arr.filter((obj) => {
        function deepFilterObj(curObj: T): boolean {
            let shouldKeep = true;
            for (const key in curObj) {
                if (Object.prototype.hasOwnProperty.call(curObj, key)) {
                    const value = curObj[key];
                    if (typeof value === 'object' && value!== null) {
                        if (!deepFilterObj(value)) {
                            shouldKeep = false;
                            break;
                        }
                    } else if (!filterFn(value, key, curObj)) {
                        shouldKeep = false;
                        break;
                    }
                }
            }
            return shouldKeep;
        }
        return deepFilterObj(obj);
    });
}

// 按属性分组函数
function groupBy<T, K extends keyof T>(arr: T[], key: K): Map<T[K], T[]> {
    const map = new Map<T[K], T[]>();
    arr.forEach((obj) => {
        const groupValue = obj[key];
        if (!map.has(groupValue)) {
            map.set(groupValue, []);
        }
        map.get(groupValue)!.push(obj);
    });
    return map;
}

确保类型安全和扩展性

  1. 类型安全
    • 使用 TypeScript 泛型来定义函数参数和返回值的类型,确保传入和返回的数据类型符合预期。
    • deepFilter 中,FilterFunction 类型定义明确了过滤函数的参数类型,从而保证过滤逻辑的类型安全。
    • groupBy 中,K extends keyof T 确保了分组属性是对象的有效属性,避免运行时错误。
  2. 扩展性
    • 对于深度过滤函数,过滤逻辑通过 FilterFunction 回调函数实现,这样可以根据不同需求传入不同的过滤逻辑,具有很强的扩展性。
    • 按属性分组函数中,泛型 TK 使得函数可以适用于不同类型的对象数组和不同的分组属性,易于扩展到各种数据结构。如果未来需要处理更复杂的分组逻辑,例如多级分组,可以在现有逻辑基础上进行扩展,通过增加参数或嵌套 Map 等方式实现。