可迭代getter的语法?

时间:2018-04-13 13:21:32

标签: typescript generator getter

我可以声明getter,它的行为与函数发生器相似吗?

我的尝试

class Foo {
    * Test1(): IterableIterator<string> { // Works, but not a getter...
        yield "Hello!"; 
    }

    * get Test2(): IterableIterator<string> { // Syntax error
        yield "Hello!"; 
    }

    get * Test3(): IterableIterator<string> { // Syntax error
        yield "Hello!"; 
    }

    get Test4(): IterableIterator<string> { // Works, but ugly syntax...
        return function* (): IterableIterator<string> {
            yield "Hello!";
        }();
    }
}

例如在C#中,这是完全有效的......

class Foo
{
    IEnumerable<string> Test
    {
        get
        {
            yield return "Hello!";
        }
    }
}

2 个答案:

答案 0 :(得分:1)

TypeScript或JavaScript中没有这样的语法。 getter应该返回一个迭代器:

class Foo {
    private * _bar() {
        yield "Hello!"; 
    }

    get bar(): IterableIterator<string> {
        return this._bar();
    }
}

这可以通过装饰器解决,但由于装饰器不能很好地支持类突变,所以应该手动处理正确的输入:

function get<T>(getter: keyof T) {
    return (target: any, method: string, descriptor?: any) => {
        Object.defineProperty(target, getter, {
            configurable: true,
            enumerable: false,
            get() {
                return this[method]();
            }
        });
    }; 
}

interface Foo {
    bar: IterableIterator<string>;
}
class Foo {
    @get<Foo>('bar')
    private * _bar() {
        yield "Hello!"; 
    }
}

答案 1 :(得分:0)

如果您不想创建私有生成器方法,可以执行以下操作:

class WithIterableGetter {
  a: string
  b: string
  constructor() {
    this.a = 'abc'
    this.b = 'bcd'
  }

  get getter(): IterableIterator<string> {
    let i = 0;
    let self = this;
    return {
      next: function() {
        return {
          done: i > 1,
          value: self[i++ === 0 ? 'a' : 'b']
        };
      },
      [Symbol.iterator]: function() { return this; }
    }
  }
}

for (const i of new WithIterableGetter().getter) {
  console.log(i)
}