facebook / facebook/flow

Getter and setter variances change depending on whether both are present

Open
#3,984 0 comments 0 reactions 0 assignees View on GitHub
bug Typing: property variance
Dominant language
Rust
Stars
22.3k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

I've recently discovered that Flow's getter/setter polarities vary counter-intuitively. When only a getter or only a setter is present, then Flow takes the corresponding field as covariant or contravariant, respectively. When both a getter and a setter are present, however, Flow takes the field as invariant. Since Flow currently has no notation (that I know of) to specify an invariant getter or setter, an extension class cannot complete the pair for an older class, e.g.

```js
class A {
// `f` is covariant
get f(): number { return 0; }
}
class B extends A {
// this is an error because I've overridden a covariant field with a contravariant one
set f(n: number) { console.log(n); }
}
```

This seems like bad manners. Ultimately, this behavior traces to `Type.Property.polarity`, [src/typing/type.ml#L990-992](https://github.com/facebook/flow/blob/4b126172b0e3ec7e581314d7f9887934b6079b99/src/typing/type.ml#L990-L992). I've noticed one place that implicitly depends on the current behavior, [src/typing/flow_js.ml#L7513-L7519](https://github.com/facebook/flow/blob/4b126172b0e3ec7e581314d7f9887934b6079b99/src/typing/flow_js.ml#L7513-L7519); it has an analogue under `set_prop`. Any plans to shift getters and setters to uniformly invariant, where the `+` and `-` variance operators admit overrides?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.