我有一个带有以下签名的函数
public async sequenceAnimations(animations: AnimationPlayer[] | AnimationTracker[]): Promise<any>
Run Code Online (Sandbox Code Playgroud)
在函数本身中,我想根据它是 AnimationPlayer 数组还是 AnimationTracker 数组进行分支,所以我尝试了以下方法:
let mappedAnimations = animations;
if (animations instanceof Array<AnimationTracker>) {
mappedAnimations = animations.map(anim => anim.animationPlayer)
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我试图允许调用者传递一个 AnimationPlayer 数组或一个包含 animationPlayer 实例的 AnimationTracker 数组。但是在使用类型检查数组的实例时出现错误
“instanceof”表达式的右侧必须是“any”类型或可分配给“Function”接口类型的类型。
另外,自动完成功能不会在 if 块中注册数组的类型,因此我认为我无法像这样检查数组类型。
确定传递的数组类型的正确方法是什么?
您不能instanceof与带有类型参数的泛型类型一起使用。编译后,所有泛型都会被删除,因此animations instanceof Array<AnimationTracker>会变成animations instanceof Arraywhich 不会执行您期望的操作。
由于在 Javscript 中数组不是类型化的,因此没有内置的方法来区分数组AnimationPlayer[]和AnimationTracker[]数组是否为空,因此在运行时它们实际上是无法区分的。但是,您可以创建一个自定义类型保护,它使用数组中的第一个非空项来确定类型。对于空数组,这总是会返回false,但在大多数情况下这可能是一个不错的解决方案:
function isArrayOf<T>(array:any[], cls: new (...args: any[]) => T) : array is T[] {
for(let item of array) {
if(item != null) return item instanceof cls;
}
return false;
}
async function sequenceAnimations(animations: AnimationPlayer[] | AnimationTracker[]): Promise<any> {
let mappedAnimations = animations;
if (isArrayOf(animations, AnimationTracker)) {
// animations is AnimationTracker[]
mappedAnimations = animations.map(anim => anim.animationPlayer);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4037 次 |
| 最近记录: |