typescript 声明实现可迭代< T>是多余的

plicqrtu  于 2023-02-05  发布在  TypeScript
关注(0)|答案(1)|浏览(140)

我的类 Package 了一个可迭代对象并实现迭代,如下所示:

[Symbol.iterator]() { return this.range[Symbol.iterator](); }

编译器 * 不强制 * implements Iterable<T>信息-为什么?

class SomeWrapper /* implements Iterable<number> */ {
  constructor(public readonly range: MyRange) {}
  [Symbol.iterator]() { return this.range[Symbol.iterator](); }
}

class MyRange {
  constructor(
    public readonly begin: number,
    public readonly end: number
  ) {}

  [Symbol.iterator]() {
    return new MyRangeIterator(this);
  }
}

class MyRangeIterator implements Iterator<number>
{
  public index: number
  public end: number

  constructor(range: MyRange)
  {
    this.index = range.begin;
    this.end = range.end 
  }

  public next(): IteratorResult<number, "no_more_values">
  {
    if (this.index < this.end) {
      return { done: false, value: this.index++ }
    }
    return { done: true, value: "no_more_values" }
  }
}

用法:

const range = new MyRange(5, 14);
const wrapper = new SomeWrapper(range)
for (const x of wrapper) { // I expected an error here: SomeWrapper - Not Iterable
  console.log(x)
}
wrrgggsh

wrrgggsh1#

TypeScript不检查类implementsIterable,但检查类是否具有Symbol.iterator属性。
当您移除此属性或使此属性不返回迭代器时,它将不再进行类型检查。
Iterators and Generators对此进行了解释。
如果一个对象具有Symbol.iterator属性的实现,则该对象被视为可迭代的。
TypeScript通常以这种方式进行类型检查,因为它基于structural subtyping
例如,即使Y不是implementsX,也会执行类型检查。

interface X {
    readonly x: string;
}

class Y {
    readonly x: string = 'y';
}

function f(x: X): void {}

f(new Y());

相关问题