flow icon indicating copy to clipboard operation
flow copied to clipboard

Support computed class properties

Open jamiebuilds opened this issue 8 years ago • 9 comments

Computed properties in objects were added (#252), but computed properties in classes are still unsupported.

class Component {
  ["foo"]() {} // known
}
declare function foo(): string;
class Component {
  [foo()]() {} // unknown
}

jamiebuilds avatar Aug 18 '16 22:08 jamiebuilds

@thejameskyle anything on this yet ?

git-jiby-me avatar Jan 29 '17 15:01 git-jiby-me

@git-jiby-me Not yet, we'll update the issue when progress has been made

jamiebuilds avatar Jan 30 '17 17:01 jamiebuilds

As this still isn't fixed, does anyone have a workaround?

I want to make an iterable class like this:

class Foo {
  [Symbol.iterator]() {
    // ...
  }
}

Is there any way to do it?

callumlocke avatar Apr 03 '17 11:04 callumlocke

@callumlocke something like this:

class Foo {
  
  constructor() {
    (this: any)[Symbol.iterator] = this._iterator;
  }
  
  _iterator(): Iterator<number> {
    return (function *() {
      yield 1;
      yield 2;
      yield 3;
    }())
  }
  
  @@iterator(): Iterator<number> {
    throw new Error();
  }
}

vkurchatkin avatar Apr 03 '17 12:04 vkurchatkin

it's a bit annoying, but if you use babel for transpiling, you cannot use the @@iterator() syntax :crying_cat_face:

madbence avatar Apr 03 '17 12:04 madbence

In that case you can escape it using comments:

class Foo {
  
  constructor() {
    (this: any)[Symbol.iterator] = this._iterator;
  }
  
  _iterator(): Iterator<number> {
    return (function *() {
      yield 1;
      yield 2;
      yield 3;
    }())
  }
  /*::
  @@iterator(): Iterator<number> {
    throw new Error();
  }
  */
}

vkurchatkin avatar Apr 03 '17 15:04 vkurchatkin

On a related note, does anyone have a work-around that would allow me to create an isIterable function that Flow could used to disambiguates the type of the argument I pass to it, for example:

if (isIterable(val)) {
  // Flow should know that `val` has type `Iterable<T>` on this branch of the guard
}
else {
  // Vs type `T` on this branch of the guard
}

doesn't work when isIterable is defined in an obvious way like this:

const isIterable = <T> (obj: T | Iterable<T>): boolean =>
  typeof (obj: any)[Symbol.iterator] === 'function';

Any smart ideas?

dchambers avatar Jun 28 '17 16:06 dchambers

computed properties would be needed for symbol property keys. @thejameskyle babel currently parses type properties in brackets as ObjectTypeIndexers, which is kind of awkward because that's not really what [someSymbol]: someType is doing...

// for sequelize...

declare opaque type And = symbol;
declare opaque type Or = symbol;

declare interface WhereLogic {
  [And]?: WhereLogic,
  [Or]?: Array<WhereLogic>,
  [field: string]: any,
}

jedwards1211 avatar Nov 08 '17 17:11 jedwards1211

Would be useful for static computed properties too.

somewhatabstract avatar Apr 27 '19 17:04 somewhatabstract