Skip to content
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

allow decorators for functions #7318

Open
zpdDG4gta8XKpMCd opened this issue Mar 1, 2016 · 25 comments
Open

allow decorators for functions #7318

zpdDG4gta8XKpMCd opened this issue Mar 1, 2016 · 25 comments
Labels
Domain: Decorators The issue relates to the decorator syntax Suggestion An idea for TypeScript Waiting for TC39 Unactionable until TC39 reaches some conclusion

Comments

@zpdDG4gta8XKpMCd
Copy link

did a quick search, it looks like this hasn't been yet requested

currently decorators can only be added to classes, methods and properties

consider allowing them on functions too

@tinganho
Copy link
Contributor

tinganho commented Mar 1, 2016

@Aleksey-Bykov it was discussed in here #2249 (comment)

@mhegazy mhegazy added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Mar 1, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Mar 1, 2016

Please note that decorator proposal is undergoing churn now, and we would not be adding new features until we have a stable proposal.

@IgorMinar
Copy link

IgorMinar commented May 25, 2016

@mhegazy just fyi that function expression decorators are at stage 0: https://github.com/tc39/proposals/blob/master/stage-0-proposals.md

And while the underlying implementation is undergoing some churn, the syntax has been stable for quite a while. It would be great to have this implemented behind a flag because angular users could then write tests with a much nicer syntax.

it('should do foo', @Injectable()(fooService:FooService) => {
...
});

compared to the current:

it('should do foo', inject([FooService], (fooService:FooService) => {
...
});

@majo44
Copy link

majo44 commented Dec 8, 2016

Any progress ? This will be really powerful feature. There is a lot of use cases.
I see on roadmap just support for function expression/arrow functions :(
I know the problem is with function hoisting.
But I think we can loos hoisting for decorated functions (especially if we are using modules).
Compiler is able to detect decorated function hoisting (and cycles) and just throw error.
I beg, do not give up :)

Related discussion:
wycats/javascript-decorators/Allow decorators for functions as well

@Thinkscape
Copy link

This could potentially solve #10644 - it's a nasty side-effect when trying to use using bound methods feature with decorators :-(

@mhegazy mhegazy added the Domain: Decorators The issue relates to the decorator syntax label Jan 4, 2017
@aluanhaddad
Copy link
Contributor

aluanhaddad commented Apr 14, 2017

My understanding of this issue is:
Decorators were added due mitigate the lack of expressiveness that was inherent in the maximally minimal approach to classes that TC39 took.

My crude paraphrasing of the above is:
ES2015 classes are basically useless without decorators. They are a travesty of a class implementation.

Do they offer conciseness? No.

Do they enable expressing anything that is not better expressed with factories? Not for me.

Do they offer compositional approaches aside from unmaintainable 5+ class deep hierarchies? No.

Do the enable composition over inheritance? No. (ignoring all the lessons learned in C++, C#, Java)

Do they encourage depending on implementation? Yes!

Do they provide encapsulation? No.

The Maximally Minimal appraoch fell flat on its face. The only reason to use classes is to use decorators, the feature has been proposed to make up for how worthless they are.

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Apr 14, 2017

Wow, that was a fast 3 👎.
UPDATE: 2 👎 (thanks @majo44 for reconsidering 😆)

I am not saying decorators should not be allowed on functions.
I am saying that the reason they are not is because they were only added to make up for classes being useless.

Again Maximally Minimal approach to decorators is what leads that feature to be insufficiently generalizable to other constructs.
I would like to have function decorators.
I also want them on object literals because of the clean declarative syntax they offer.

@Durisvk
Copy link

Durisvk commented Dec 5, 2017

Is this even possible? I saw a discussion on Babel about this and they ended up with impossibility to implement decorators on function because of their hoisting.

Is hoisting acceptable in TypeScript? (I don't know because I've never used that)

@huan
Copy link

huan commented May 13, 2018

I beg, do not give up +1

@hax
Copy link

hax commented Jun 4, 2018

The standardization effort of function decorators has been moved to https://github.com/iddan/proposal-function-expression-decorators . The decorator of function declarations and the hoisting problem is discussed in No. 3 issue.

@OmgImAlexis
Copy link

Is there any news on this? Looks like nothing really changed in the last year or so.

@mjeri
Copy link

mjeri commented Mar 6, 2020

AFAIU this is still blocked by the lack of JavaScripts ability to do that.

@Exeteres
Copy link

Exeteres commented Jul 7, 2020

Hi there!
I just created a simple plugin that enables function decorators.
It is a system of two plugins: tsserver plugin that removes errors and ts-patch (ttypescript) plugin that transforms decorated function to the corresponding expression.

Example

image
image

For some reason, this plugin can only be used with ts-patch, not with ttypescript.
And of course there are some limitations.

@andreujuanc
Copy link

If the argument is that this will break hoisting, GOOD THEN. I hate hoisting anyways 😆

Jokes aside, the fact that decorators can only be used on classes is totally arbitrary. Everything is possible. Even a dangling decorator are technically possible to implement. This thread is more like convincing the right people to actually make it happen.

@bal1anD
Copy link

bal1anD commented Jun 14, 2021

Any updates on this? This will be a very valuable feature

@MartinJohns
Copy link
Contributor

@bal1anD Just check yourself:

The standardization effort of function decorators has been moved to https://github.com/iddan/proposal-function-expression-decorators .

The proposal is still stage 0. It builds upon the decorator porposal, which is still only stage 2. Don't expect this anytime soon.

@RyanCavanaugh RyanCavanaugh added Waiting for TC39 Unactionable until TC39 reaches some conclusion and removed In Discussion Not yet reached consensus labels Jun 14, 2021
@menocomp
Copy link

Using decorators in functions! Why?
We can use higher order functions that is even much better and handle more use cases that decorators can not handle.

@bal1anD
Copy link

bal1anD commented Mar 18, 2022

@menocomp: well, in that case, why introduce decorators in TS at all? All of their use-cases can be solved by higher-order functions? The reason is elegance, clean-code.

@andreujuanc
Copy link

@bal1anD not only that but some people find this feature useful
image

@vegerot
Copy link

vegerot commented Apr 14, 2022

This would be helpful as well

@radarsu
Copy link

radarsu commented Jul 22, 2022

Using decorators in functions! Why? We can use higher order functions that is even much better and handle more use cases that decorators can not handle.

I agree, we shouldn't care about "syntax sugars" which introduce layer over layer over layer just to reduce negligible amount of additional characters typed. And I certainely don't think introducing new constructs to the language actually makes code "elegant" and "clean". Usually it makes code shorter, but often tradeoff is that code becomes harder to reason and learnng curve is getting steeper and we all know too "smart" short code is no good. Imagine Junior programmer reading code top-down. I bet such person won't know how decorators work, when they are executed etc. They're not self-explanatory like higher-order functions which you understand quickly when you grasp that function can return function. Decorators feel a bit like "magic" and that's it for dozens of juniors.

But the core problem here is with additional value provided by decorators in TypeScript via experimentalDecorators and emitDecoratorMetadata flags for classes, which is very useful and good reason to use them. For example ability to obtain metadata about function parameter types provided by compiler to the runtime. I don't think such feature is currently possible without "Class" construct.

From my perspective this is what makes current state of TypeScript favor OOP over Functional Paradigm, especially when it comes to solving problem of dependency injection conviniently, which is an extremely important one.

@aspirisen
Copy link

Decorators for function would be extremely useful for react, so instead of this:

export const Component = forwardRef(function Component() {
    return <div>Component</div>
})

// or

function Component() {
    return <div>Box</div>
}

const _Component = forwardRef(Component)

export { _Component as Component }

We could have just

@forwardRef
function Component() {
    return <div>Component</div>
}

@nowaysgit
Copy link

  • 1 !

@tareksaleem
Copy link

I think this could be done using a hack
instead of waiting for js to support decorators or change things in hoisting we do something different
basically all what is needed from typescript is supporting the syntax itself and this syntax could be transpilled to javascript syntax normally, how this could be done?

aft first anonymous functions could not be supported so let's stick with functions and suppose we have this function:

@logger
function fetchData() {
  await fetch('resource')
}

logger actually will not be a class or method decorator to avoid dealing with descriptors, instead of that it will be a higher order function as the following:

function logger(target) {
  return (...args) {
    // do whatever you want
    return target(...args)
  }
}

when typescript compile the code it should output something like this:

function fetchData() {
   logger()
  // ...other decorators
  return _fetchData();
}

I think this could be a start

@MartinJohns
Copy link
Contributor

I think this could be done using a hack
instead of waiting for js to support decorators

Auch hacks are explicitly out of scope for TypeScript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: Decorators The issue relates to the decorator syntax Suggestion An idea for TypeScript Waiting for TC39 Unactionable until TC39 reaches some conclusion
Projects
None yet
Development

No branches or pull requests