首页 > 解决方案 > 类型保护没有像预期的那样缩小泛型类型。“T”可以用与“数字”无关的任意类型实例化

问题描述

我有一个插入值的函数,用于为对象设置动画。值可以是数字、数字数组或包含数字/数字数组的对象,尽管这对于即将描述的问题并不重要。

这是源代码的骨架,可在此TS 游乐场链接中找到:

function lerpGeneric<T>(from: T, to: T, progress: number): T {
    if (typeof from !== typeof to) {
        throw Error(`The types of 'from' and 'to' do not match. Got ${typeof from} and ${typeof to}`);
    }

    switch (typeof from) {
        case 'number':
            if (typeof to === 'number')
                return lerpNumber(from, to, progress); // Error! 'T' could be instantiated with an arbitrary type which could be unrelated to 'number'.
            else
                throw Error(`Expected type of 'to' to be number but got ${typeof to}.`);
        case 'object':
            // If array, clone and iterate over each item.
            // If object, clone and recurse over properties.
        default:
            // not lerp-able, throw error.
    }

}

// Linearly interpolates a value. Progress is a number from 0 to 1.
function lerpNumber(start: number, end: number, progress: number): number {
    return start + (end - start) * progress;
}

在标有 的行 // Error!。编译器抱怨返回的类型。switch对我来说, and的类型检查if应该(有效地)缩小Tto的类型number,但这不会发生。编译器说'T' could be instantiated with an arbitrary type which could be unrelated to 'number'.有趣的是,VSCode 建议了fromtoto be的类型T & number,而不仅仅是number,就像我期望的那样。无论如何,编译器警告是什么?我想不出任何T返回typeof T === 'number'anumber可能导致运行时错误的类型。有没有办法在这里更正处理类型,还是我只需要在这里执行类型断言?

标签: typescriptgenerics

解决方案


TypeScript 错误地推断出的类型fromT & numberwhen,事实上,它只能number在那个时候。它看起来像一个 TypeScript 错误,你肯定不是第一个注意到它的人。

在修复此 TypeScript 错误之前,请if使用switch.


推荐阅读