-
Notifications
You must be signed in to change notification settings - Fork 127
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
Exports and decorators #7
Comments
Good point, the middle code should desugar to this to allow this behaviour: var Foo = (function () {
class Foo {
}
Foo = dec(Foo) || Foo;
return Foo;
})();
export default Foo; |
AFAIK this: export default class C {} already desugars to: class C {}
export default C; So this is a non-issue. Please @sebmck check me on this. |
I can file it but I'll make sure this is the case when @sebmck chimes in. |
I don't think the grammar specifically allows it but it should be allowed. |
The grammar (If I'm reading it correctly) allows you to do: export default @decorator class Foo {} |
FYI @sebmck Babel's decorator transform does not allow that. Shall I raise an issue? |
@keithamus No it does. I just haven't pushed the latest version to that site. |
Sweet, many thanks @sebmck! Awesome work! Back on point - this become a pain point for ES6? |
It may or may not be worth mentioning that TypeScript's WIP branch for ES6/decorators (demo'd for Angular 2.0) supports decorators before the export declaration. This doesn't appear to be inline with the outlined spec here, but just wanted to note real-world user assumptions. @decorator export default class Foo {} Everything else seems the same. |
For TypeScript, we've been working with the idea that @decorator
export class C {
@decorator
static method() {
}
} As opposed to: export
@decorator
class C {
@decorator
static method() {
}
} |
@rbuckton the problem with that syntax is that it forecloses the ability to ever decorate exports themselves, no? |
@wycats Wouldn't you instead be decorating the declaration that is being exported? I'd rather look into ways of qualifying a decorator in a future proposal. Something similar to how you can disambiguate attributes in C#. An example might be: @module: moduleDecorator // decorator for module
@export: exportDecorator // decorator for export
@constructor: classDecorator // decorator for class (default)
@classDecorator // decorator for class (default)
export class C {
@initializer: initializerDecorator // decorator for function of initializer
@property: propertyDecorator // decorator for property (default)
@propertyDecorator // decorator for property (default)
property = 1;
@return: returnDecorator // decorator for return
@method: methodDecorator // decorator for function of method
@property: propertyDecorator // decorator for property (default)
@propertyDecorator; // decorator for property (default)
method() {
}
@method: methodDecorator // decorator for function of get accessor
@propertyDecorator // decorator for property (default)
get accessor() {}
@method: methodDecorator // decorator for function of set accessor
set accessor(value) {}
method2(
@param: parameterDecorator // decorator for parameter (default)
@parameterDecorator // decorator for parameter
p) {
}
} Parsing decorator before |
@wycats Maybe I'm misunderstanding, but decorating exports over classes sounds a bit like a footgun to me: @foo
export default class Bar() {}
// lets say the above desugars to this in Node-land:
Bar = foo(module.exports = function Bar() {}) || Bar; So my Bar class has been exported, and then the exports reference gets decorated - but outside of the assignment, meaning the |
@keithamus That's not necessarily how it might work since the semantics for it haven't been invented yet. 😄 What @wycats said was that it's problematic to rush into adding additional syntax since it forecloses the ability to do something special with it in the future. |
I'm curious what the current state of this grammar is. In Babel, at present, it is possible to do this:
However I can't find that syntax described in the grammar given with this proposal. Is the github doc out of date, or is the Babel behavior taken from somewhere else? |
Any thoughts on allowing something like this? @curry
export * from 'mod' Where 'curry' would be applied to each element exported by mod. |
@bathos, I think that you just didn't notice:
|
@ashaffer what's the case? |
@trikadin You mean what's the use-case? Suppose I have some library of functions and I want to compose them all with some other function, or curry them all, or whatever. Right now I have to do: import {fn1, fn2, fn3} from 'mod'
fn1 = curry(fn1)
fn2 = curry(fn2)
fn3 = curry(fn3)
export {
fn1,
fn2,
fn3
} This would be much nicer and equally declarative if I could just indicate that I would like to apply a transformation to each element of @curry
export * from 'mod' |
@ashaffer Your example is invalid in this case. Imported bindings are immutable, that should throw an exception because you are reassigning them. The core issue with that is that
where you could potentially loop over every property and call the decorator on it. It's more like
|
@loganfsmyth That does make sense, I didn't realize they were being exported in that way. However, since exports are immutable, would it not be possible to do something like this? const modExports = require('mod');
for (const key in modExports){
const cache = {}
Object.defineProperty(exports, key, {
get(){
return cache.hasOwnProperty(key)
? cache[key]
: (cache[key] = decorator(modExports[key]));
}
});
} In this way, you preserve the late-binding nature of exports that facilitates cyclic dependencies. |
@trikadin, decorating classes isn't what I was referring to. The grammar does clearly cover the example you gave:
However, Babel currently* supports an extension of the Short version: which of the following is true?
(Or: something else entirely.) * Edit: well, not currently I should say, since decorators aren't covered by Babel 6 at the moment. |
@ashaffer It's not just late binding though, it's a fully live binding. Exports are immutable from the outside, they are mutable from the inside. For instance a module is perfectly allowed to do the following
Every time the
|
@wycats as of babel 6.5.1, the current behavior is that of sigh TypeScript, please close as fixed. |
Within a module, which only exports one class, the easiest syntax to use is as follows:
However, it seems this could be incompatible with class decorators. Would the following work?
Or would you have to do:
The text was updated successfully, but these errors were encountered: