我有一个内插值的函数,该值用于为对象设置动画。值可以是数字,数字数组或包含数字/数字数组的对象,尽管这对于即将描述的问题并不重要。
这里是源的骨架,可以在此TS playground link上找到:
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
和if
的类型检查应(有效地)将T
的类型缩小到number
,但这不会发生。编译器说'T' could be instantiated with an arbitrary type which could be unrelated to 'number'.
有趣的是,VSCode建议将from
和to
的类型设为T & number
,而不是我所期望的number
。无论如何,编译器警告什么?我想不出任何类型T
,其中typeof T === 'number'
仍返回number
可能会导致运行时错误。这里有一种方法可以纠正句柄类型,还是我只需要在这里执行类型断言?
答案 0 :(得分:1)
TypeScript错误地推断from
的类型为T & number
,而实际上此时只能为number
。它看起来像是TypeScript错误,您肯定not the first注意到了它。
在修复此TypeScript错误之前,请使用if
代替switch
。