【问题标题】:How to extend IterableIterator in TypeScript如何在 TypeScript 中扩展 IterableIterator
【发布时间】:2021-03-28 23:59:23
【问题描述】:

我正在尝试使用 where 方法扩展 Iterable,类似于 C# Enumerable.where()。扩展Array 原型很容易,但是我正在努力寻找如何扩展Iterable

声明如下:

declare interface Iterable<T> {
    where<T>(this: Iterable<T>, predicate: (item: T) => boolean): Generator<T>;
}

问题在于实施。扩展方法编译得很好,但是在运行时尝试在Array(这是一个Iterable)或任何Iterable 上使用该方法时,它会抛出where() 未定义。在Array 上,您只需将方法实现添加到Array.prototype,但Iterable 没有原型:

function* where<T>(this: Iterable<T>, predicate: (item: T) => boolean): Generator<T> {
    for (const item of this) {
        if (predicate(item)) {
            yield item;
        }
    }
}

Iterable.prototype = function* where(...) 不起作用,因为Iterable 没有原型。

这是所需的用法:

public myMethod(myIterable: Iterable<number> ) {
    console.log(myIterable.where(i => i > 3));
}

如何扩展Iterable?我应该扩展IterableIterator 吗?

有人设法在另一个线程 (https://stackoverflow.com/questions/62008192/typescript-`extending`-iterableiterator-for-array-type-but-return-a-simple-type) 上做,但他没有展示他如何扩展 Iterable 并告诉我再问一个问题。

【问题讨论】:

  • 每个可迭代对象都通过设计实现自己的迭代器,以便每个自定义迭代器都可以适应可交互对象的独特结构。提供通用功能会破坏设计理念。因此,没有“Iterable”接口或对象可供使用。

标签: javascript typescript


【解决方案1】:

您可以扩展 IteratorPrototype,在这种情况下,您的方法将适用于内置的迭代器,如 array.keys() 或星型函数,但不适用于数组等可迭代对象。

正如你所说的那样,没有办法扩展Iterable,因为在运行时不存在这样的东西。一般来说,更常见的做法是设计自己的“monad”,而不是扩展内置原型:

result = Enumerable(someIterable)
    .where(...)
    .map(...)
    .etc(...)
    .toList()

【讨论】:

  • 是的,这就是我得出的结论;制作我自己的 Enumerable 类。谢谢
猜你喜欢
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 2017-04-18
  • 2019-09-16
  • 1970-01-01
  • 2013-07-09
  • 2016-08-14
相关资源
最近更新 更多