首页 > 解决方案 > 在 TypeScript 中按类型查找数组中的值

问题描述

我正在尝试构建一种按类型在数组中查找项目的方法。考虑这个特定的设置:

abstract class Animal {}

class Dog extends Animal {}
class Cat extends Animal {}
class Horse extends Animal {}

const animals: Animal[] = [new Dog, new Cat, new Horse];

我正在尝试编写一个函数,该函数可以animals从其类型中找到一个元素,例如:findAnimal<Dog>(animals). 用简单的英语:“find the first element of animalsthat is an instance of Dog。” 这是一个粗略的草图:

function find<A extends Animal>(items: Animal[]): A {
    return items.find((a: Animal) => a instanceof A) as A;
}

这不会编译,我理解为什么:编译后该通用参数不再存在。但是,有没有办法让这样的事情起作用?我当然可以修改函数以采用两个参数:

function find(items: Animal[], A: NOT_SURE_WHAT_GOES_HERE): WHAT_TO_RETURN {
  // ...
}

但是,通过此更改,我不确定如何正确指定第二个参数或返回类型。我有哪些选择?

标签: typescript

解决方案


您可以在类参数的类型和返回值中使用泛型,如下所示:

function find<A extends Animal>(animals: Animal[], cls: new() => A): A | undefined {
    return animals.find((value): value is A => value instanceof cls);
}

请注意,通过使用类型谓词作为find回调的返回值,我们不再需要类型断言。这更安全 - 您可能在 中找不到cls实例animals,您可能会undefined as A在当前实现中返回。

当您调用它时,可以从第二个参数推断出泛型:

find(animals, Dog);

操场


推荐阅读