Typescript 类型保护未按预期缩小泛型类型';T';可以使用与';无关的任意类型进行实例化;编号';

Typescript 类型保护未按预期缩小泛型类型';T';可以使用与';无关的任意类型进行实例化;编号';,typescript,generics,Typescript,Generics,我有一个插值函数,用于为对象设置动画。值可以是数字、数字数组或包含数字的对象/数字数组,尽管这对于即将描述的问题并不重要 以下是源代码的框架,可在以下位置找到: 函数lerpGeneric(from:T,to:T,progress:number):T{ if(typeof-from!==typeof-to){ 抛出错误(`from'和`to'的类型不匹配。获取了${typeof from}和${typeof to}`); } 开关(类型自){ 案件编号: if(typeof to==‘numbe

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

以下是源代码的框架,可在以下位置找到:

函数lerpGeneric(from:T,to:T,progress:number):T{
if(typeof-from!==typeof-to){
抛出错误(`from'和`to'的类型不匹配。获取了${typeof from}和${typeof to}`);
}
开关(类型自){
案件编号:
if(typeof to==‘number’)
return lerpNumber(from,to,progress);//错误!T可以用与“number”无关的任意类型实例化。
其他的
抛出错误(`预期的'to'类型是数字,但得到了${typeof to}.`);
案例“对象”:
//如果是数组,则克隆并迭代每个项。
//如果是对象,则在属性上克隆和递归。
违约:
//不可编辑,抛出错误。
}
}
//线性插值一个值。进度是一个从0到1的数字。
函数lerpNumber(开始:编号,结束:编号,进度:编号):编号{
返回开始+(结束-开始)*进度;
}

在标有
//错误的行中。编译器会抱怨返回内容的类型。对我来说,
开关
if
的类型检查应该(有效地)将
T
的类型缩小到
数字
,但这不会发生。编译器说,
'T'可以用一个与“number”无关的任意类型实例化。
有趣的是,VSCode建议
from
to
的类型为
T&number
,而不是像我预期的那样,仅仅是
number
。无论如何,编译器警告是关于什么的?我想不出任何类型的
t
,其中
typeof t==='number'
,但是返回
number
可能会导致运行时错误。这里有没有纠正句柄类型的方法,或者我需要在这里执行类型断言?

TypeScript错误地推断出来自
类型是
T&number
,而实际上,此时它只能是
number
。它看起来像一个打字脚本错误,你肯定是注意到它的人

在修复此TypeScript错误之前,请使用
if
而不是
switch

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;
}