如何在Typescript中检查数组的类型?

时间:2018-02-09 14:43:14

标签: arrays typescript

我有一个带有以下签名的功能

public async sequenceAnimations(animations: AnimationPlayer[] | AnimationTracker[]): Promise<any>

在函数本身中我想基于它是否是AnimationPlayer数组或AnimationTracker数组进行分支,所以我尝试了这个:

let mappedAnimations = animations;
if (animations instanceof Array<AnimationTracker>) {
    mappedAnimations = animations.map(anim => anim.animationPlayer)
}

正如您所看到的,我正在尝试允许调用者传递AnimationPlayer数组或具有animationPlayer实例的AnimationTracker数组。但是在使用类型

检查Array的instanceof时出错
  

&#39;实例的右侧。表达式必须是&#39; any&#39;或者可以分配给&#39;功能&#39;界面类型。

自动完成也没有在if块中注册数组的类型,所以我假设我不能像这样检查数组类型。

确定传递的数组类型的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

您不能将instanceof与带有类型参数的泛型类型一起使用。编译完成后,所有泛型都将被删除,因此animations instanceof Array<AnimationTracker>将变为animations instanceof Array,这将无法达到您的预期。

由于在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);
    }
}

答案 1 :(得分:1)

简短回答:你不能

TypeScript的主要思想是在编译时添加类型,并在编译后发出纯JavaScript代码。 JavaScript本身不支持高级类型检查,因此您只能选择在运行时进行鸭子输入。

相关问题