【问题标题】:How can I check the type of an Array in Typescript?如何在 Typescript 中检查数组的类型?
【发布时间】:2018-07-20 08:52:08
【问题描述】:

我有一个带有以下签名的函数

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 时出现错误

“instanceof”表达式的右侧必须是“any”类型或可分配给“Function”接口类型的类型。

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

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

【问题讨论】:

  • 你能创建一个包装类 AnimationPlayerList 和 AnimationTrackerList 并针对这些类进行测试吗?

标签: arrays typescript


【解决方案1】:

您不能将instanceof 与带有类型参数的泛型类型一起使用。编译后所有泛型都被删除,所以animations instanceof Array&lt;AnimationTracker&gt; 会变成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);
    }
}

【讨论】:

    【解决方案2】:

    简答:你不能

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

    【讨论】:

      猜你喜欢
      • 2020-10-26
      • 1970-01-01
      • 2020-05-18
      • 2012-09-29
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      • 2022-01-08
      相关资源
      最近更新 更多