Closed srounce closed 8 years ago
@srounce please could you specify what you'd like the compiled code to look like (roughly)? It'll help me figure out if we can do this.
Sure, I'd expect a class hierarchy check (Class<T>
) to be something along the lines of:
if (!(A.isPrototypeOf(type)))
throw new TypeError("Value of argument 'type' violates contract: Not a subclass of 'A'");
The issue of whether a class was defined as a class
or a function
is slightly more complex (Class
check). Seeing as the class
keyword is just sugar over defining methods on a function's prototype chain, the definition will end up as a function
.
However, the class keyword can be detected via the class constructor's toString
method and a little bit of string searching to end up with:
if (!(A.prototype.constructor.toString().indexOf('class')))
throw new TypeError("Value of argument 'type' violates contract: Not a class");
As Babel will transpile them all to functions we cannot do this, the above comes rather unstuck (and where my current train of thought on this matter resides). Only thing that comes to mind (for this work at runtime), is modification of the syntax tree: adding tags to denote classes VS functions (not ideal).
@phpnode - It's been a while since I touched estree related stuff, how feasible does this sound to you?
Tl;dr, Class<T>
is pretty solvable Class
is a little trickier and needs more thought.
Hmm, right now we don't actually validate type parameters in polymorphic functions, we just recognise that certain identifiers are type parameters and skip their checks. I would like to solve this properly but it can get ridiculously complicated so I'm wary.
As for differentiating between Class
and Function
, I don't think there's a sensible way to do that because of proliferation of classes which don't use the new syntax. We shouldn't discriminate here, it makes no sense to say that e.g. node's Buffer
is not a class because it's not defined with class Buffer {}
.
If Class
(and therefore Class<T>
) is a thing, we could emit a very simplistic check for this, basically typeof thing === 'function' && thing.prototype && thing.prototype.constructor === thing
. I think that's the best we're going to get until the type parameters issue gets sorted.
Currently we can only specify a naive check of
Function
orFunction<T>
. If we specify a type ofClass
the plugin treats it as a variable.Given:
It would be nice if one could express:
So
factoryFn
would:type
argument was a the class definition A or one of it's sub-classesparent
argument is an instance of A or one of it's sub-classesHope this makes sense, cheers!