MST

星途 面试题库

面试题:TypeScript动画库类型安全交互之泛型与类型推断优化

为了让动画库更具通用性,需要实现一个通用的动画执行函数,该函数可以接受不同类型的动画数据(如数字、对象等)进行动画处理。请使用TypeScript的泛型和类型推断来实现这个函数,使得在调用该函数时能够根据传入的参数自动推断出正确的类型,同时确保动画过程中对数据的操作都是类型安全的。详细说明实现思路及如何利用类型系统避免潜在的运行时错误。
36.9万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 定义一个泛型函数,泛型参数代表动画数据的类型。
  2. 在函数内部,根据动画的逻辑对传入的数据进行操作,由于使用了泛型,这些操作在编译时会根据实际传入的数据类型进行类型检查。
  3. 利用TypeScript的类型推断机制,在调用函数时,编译器会自动根据传入的参数推断出泛型的具体类型,从而保证类型安全。

代码实现

function animate<T>(initialValue: T, endValue: T, duration: number, callback: (value: T) => void) {
    const startTime = performance.now();
    const step = (timestamp: number) => {
        const elapsed = timestamp - startTime;
        const progress = Math.min(elapsed / duration, 1);
        // 这里假设动画是线性插值,对于对象类型需要更复杂的处理
        const interpolatedValue = interpolate(initialValue, endValue, progress);
        callback(interpolatedValue);
        if (progress < 1) {
            requestAnimationFrame(step);
        }
    };
    requestAnimationFrame(step);
}

function interpolate<T>(start: T, end: T, progress: number): T {
    if (typeof start === 'number' && typeof end === 'number') {
        return (start + (end - start) * progress) as unknown as T;
    }
    // 处理对象类型,这里简单示例,实际可能需要深度合并等操作
    if (typeof start === 'object' && typeof end === 'object' && start !== null && end!== null) {
        const result = {} as T;
        for (const key in start) {
            if (Object.prototype.hasOwnProperty.call(start, key)) {
                result[key] = interpolate((start as any)[key], (end as any)[key], progress);
            }
        }
        return result;
    }
    return start;
}

利用类型系统避免潜在运行时错误

  1. 泛型参数检查:通过定义泛型 T,在编译时,TypeScript会检查传入的 initialValueendValue 是否具有相同的类型。如果类型不一致,编译器会报错,避免在运行时出现类型不匹配的错误。
  2. 函数参数类型检查callback 函数的参数类型被定义为 T,确保回调函数中对动画值的操作是类型安全的。如果回调函数内部对 value 的操作不符合 T 的类型定义,编译器会报错。
  3. 插值函数类型检查interpolate 函数同样使用泛型 T,在处理不同类型数据的插值时,会根据传入数据的类型进行相应的操作。例如对于数字类型直接进行线性插值,对于对象类型会递归处理属性,确保类型安全。如果插值操作不符合类型定义,编译器会报错,从而避免运行时错误。