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