-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Statics subtyping (RFC: Newable<.>
to indicate constructor subtyping)
#1847
Conversation
interface I {
anotherMethod(): number;
}
interface J {
static anotherStaticMethod(): number;
}
class MS {
anotherMethod(): number {
return 3;
}
static anotherStaticMethod(): number {
return 4;
}
}
class A {
static sm3(): Class<I> & Class<J> {
return MS;
}
}
var Y = A.sm3();
var y = new Y();
var n6: number = y.constructor.anotherStaticMethod();
ConstructorT doesn't distribute across intersection members. |
I thought interfaces should forbid
Classes created by |
666d44f
to
383c818
Compare
newable
-flag on insttype
to indicate constructor subtyping)
@@ -1848,6 +1848,24 @@ let rec __flow cx ((l: Type.t), (u: Type.use_t)) trace = | |||
(List.hd ts, | |||
LookupT (reason, strict, (List.tl ts) @ try_ts_on_failure, s, t)) | |||
|
|||
| IntersectionT (r, rep), GetPropT (reason_op, (reason_prop, "constructor"), t) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generalize with an is_set_op_distributive
gate on u
, and handle UnionT
too.
newable
-flag on insttype
to indicate constructor subtyping)Newable<.>
to indicate constructor subtyping)
@popham - I'm making an effort to clean out our oldest pull requests. What's the status of this PR? Are you waiting for feedback? Planning some more changes? Or is this abandoned? By default, I'm closing out old PRs that I can't merge. This does not reflect the quality of the PR. Please feel free to re-open this if you think it should still be open. |
tests/class_type/test2.js
--it lights up like Christmas under master). Fixes Class<> qualified interface constraints do not accept compatible classes #1705constructor
lookups across intersections.Class<X>~>Interface
flows (Class<X>
~>Class<Interface>
are allowed).A
,Class<A>
subtyping isn't analogous toA
subtyping #836, typeof X subclass #1047, Class<T> for subclass of T #1893RFC:
I feel that the sticky point here is the lack of subtyping on class constructors. Suppose class
B
extends classA
, butB
implements a constructor that doesn't subtype that ofA
.Working to the signature of
A
within...
implies a false positive, while working to the signature ofB
within...
implies a false negative. This same problem shows up in class methods thatnew this.constructor
and static class methods thatnew this
. I think that this is easily handled for implicit annotations with anewable
flag oninsttype
, but for explicit annotations the annotation's syntax would probably be ugly.newable=true
is necessary for 90% of use cases. (Hence the unification rule withinClassT~>ClassT
?)a: A
,newable=false
is sufficiently strong in 99% of use cases (1% generously fornew a.constructor
).a: A
,newable=false
is sufficiently strong in 99% of use cases.K: Class<A>
,newable=false
is sufficiently strong in 50% of use cases(?).Does there currently exist a plan and/or demand to tighten things up here? My quick and dirty thinking is the
newable
flag oninsttype
and aNewable<.>
wrapper for explicit annotations that impose constructor subtyping in addition to the norm:I think that this is preferable to some pretty-sounding variation of
NonNewable
because of the prevalence of thea: A
use case.(And currently,
Class<.>
annotations are kinda useless, aren't they? If the annotation necessarily contains the class type, then why shuffle it around? Why provide it as a parameter? I thought ES6 was spec'd to avoid circular importing problems, eliminating that possibility(?). I suspect that post-transpile, broken circular-imports may be the only credible use case.)