Flow: `Class` should be invariant

Created on 17 Jan 2017  路  4Comments  路  Source: facebook/flow

Example:

class A {}

class B extends A {
  constructor(a: number) {
    super();
    a.toFixed();
  }
}

const a: Class<B> = B;
const b: Class<A> = a;

const x = new b(); // no error
object model

Most helpful comment

Another option is not to consider class B subtype of class A if constructor B is not a subtype of constructor of A.

I like this approach

All 4 comments

This looks like a bug in that the constructor of B shouldn't be permitted (it is incompatible with A's constructor).

Consider an example with a normal method and you can see that Flow correctly errors:

class A {
  foo() {}
}

class B extends A {
  foo(a: number) {}
}

https://flowtype.org/try/#0MYGwhgzhAECC0G8BQ1oDMD2GAUBKRAvkkUqJDAELQCmAHgC7UB2AJjPMqpjmAFzRMArgFsARtQBO+BEQJA

Overall, Class<> should be covariant because static-classes in JS themselves are an "instance" of the static-class they extend.

It is very common in OOP languages to change constructor in subclasses arbitrarily (e.g. provide default args), so it will be very inconvenient.

Another option is not to consider class B subtype of class A if constructor B is not a subtype of constructor of A.

Another option is not to consider class B subtype of class A if constructor B is not a subtype of constructor of A.

I like this approach

Was this page helpful?
0 / 5 - 0 ratings