IC_
IC_

Reputation: 1789

Flowtype. Create instance of class that implements interface with optional fields

Here is an example

interface A {
  var1: string;
  var2?: string;
}

class B implements A {
   var1: string
}

const bInstance = new B({ var1: "sss" }) // no such constructor

Flow make me declare var1 as class property. So what if i have n fields? Should i rewrite all of them or there is another way to solve it?

Flow doesn't make me declare var2 as class property due to it's optional. Should i create B constructor manually as

constructor (a: any) {
  this.var1 = a.var1
  if (a.var2) {
    this.var2 = a.var2
  }
}

It look ugly. Does flow can't resolve such things automatically?

Upvotes: 1

Views: 606

Answers (1)

John Shammas
John Shammas

Reputation: 2715

If you have a known n number of fields, yes, you need to list all of them with their types. Otherwise—how would Flow understand the set of properties that are allowed?

If n is unknown, and you instead want to specify that the class can have any number of fields that are strings, you can instead consider a map:

interface A {
  someName: { [key: string]: string };
}

Keep in mind that with this format, the interface can't dictate what the exact names of those keys are.

As for your second question, your implementation of Class B…

class B implements A {
   var1: string
}

…will cause an error if you try to use the constructor in your question. When you defined var2?: string; on the interface, you told flow that "An implementing class may have var2, and if it does, it must be a string." But when you defined Class B, by not listing var2, Flow assumes B can never have var2. The interface type really doesn't help you shorten code, it only helps you ensure that your classes conform to a certain ruleset.

In the constructor, if you want to shorten your example, you can do something such as:

constructor (a: any) {
  Object.assign(this, a); // copy all properties of `a` to `this`
}

Regardless, I would highly recommend changing the type of a in your constructor to something more specific (or even just remove ": any"), else Flow will not be able to properly ensure you are passing in something appropriate.

Upvotes: 1

Related Questions