TypeScript中如何实现泛型类型的数组ofType筛选方法?
Array扩展ofType泛型方法的正确实现
问题核心在于TypeScript的泛型类型在编译阶段会被擦除,运行时根本不存在T2这个值,所以你直接写x instanceof T2肯定会报错——T2只是编译时的类型标记,不是能拿来判断的构造函数。
正确实现代码
要解决这个问题,必须让ofType方法接收目标类的构造函数作为参数,这样运行时有实际的值可以用来做instanceof判断,同时TypeScript也能通过构造函数自动推导泛型类型。
class Animal {} class Musquito extends Animal {} class Dog extends Animal {} // 扩展Array的接口定义 interface Array<T> { ofType<T2 extends T>(ctor: new () => T2): T2[]; } // 实现ofType方法 Array.prototype.ofType = function <T2>(ctor: new () => T2): T2[] { // 用类型守卫x is T2让TS确认过滤后的元素类型 return this.filter((x): x is T2 => x instanceof ctor); }; // 调用示例 const lst: Animal[] = [new Musquito(), new Dog()]; const dogs = lst.ofType(Dog); // 自动推导返回类型为Dog[]
关键细节
ctor: new () => T2:这个类型表示传入的是一个能创建T2实例的构造函数,同时T2 extends T限制了目标类型必须是数组元素类型的子类,避免传入无关类型。x is T2:这是TypeScript的类型守卫,告诉编译器经过instanceof ctor判断后的元素确实是T2类型,不需要再用as T2[]强制转换,类型更安全。- 调用时直接传
Dog构造函数即可,TypeScript会自动推导泛型类型,不用手动写ofType<Dog>()(当然硬要写也可以:lst.ofType<Dog>(Dog),但完全没必要)。
内容的提问来源于stack exchange,提问作者Wouter Vandenputte
相关产品推荐
相关产品推荐

