-
Notifications
You must be signed in to change notification settings - Fork 106
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
Decorators for all definitions #440
Comments
I realize the implementation effort may be significant for transpilers due to the nature of how getter/setters function exclusively on properties of objects. In order for a decorator a variable, constant, or parameter, then perhaps each decorator kind should be Having top-level accessors and allowing them to be decorated with decorators enables a very elegant syntax sugar which not only can we apply a runtime type system as mentioned above, but also functional reactive programming (FRP) patterns: let @reactive() seconds = 23
let @reactive(num) minutes = parseInt(seconds / 60)
setInterval(() => {
seconds += 1
}, 1000)
function getTimeString() {
return `${minutes} minutes and ${seconds} seconds`
} In this example, a runtime and a function
What this means to illustrate is not valid use-case that is enabled by extending the definition of the decorator proposal. Hopefully this strengthens the argument for such an extension. TranspilersIt is conceivable that transpilers could implement this syntactic and semantic change to JS by transpiling any occurrence of an identifier which has been semantically changed from a "regular variable/constant" to an "accessor variable/constant" by replacement: let @decorator foo = 23
console.log(foo)
foo = 42
// becomes
var foo = _decorator(_initAccessor(() => 23 ).value)
console.log(foo.value)
foo.value = 42 In short, the identifier is replaced with an object containing a single accessor called |
what you have proposed has already been in the EXTENSION.md of this repo. https://github.com/tc39/proposal-decorators/blob/master/EXTENSIONS.md#let-decorators |
I wasn't aware of these extensions. Good to know. Looks like it covers most of what I mentioned in this issue. However, one other thing it doesn't cover and I haven't quite mentioned, is the idea to decorate the only return value of a function: function name() @decorator {
return value
}
const name = () @decorator => value Unless I missed it, this would be worthwhile to add to consideration in the extensions. Having this could be useful to be able to decorate just the return value. Otherwise, the only way to decorate the return value would be to decorate the entire function declaration or assignment value for an identifier and this would require a transformation of decorator kinds: const decoratorForAccessors = ...
// Will work
const @decoratorForAccessors foo = value
// WIll not work
@decoratorForAccessors
function foo() {
// ...
}
// Will work if you wrap with some transformer
@applyToReturn(decoratorForAccessors)
function foo() {
// ...
} |
I'm a big fan of decorater, But in mainstream Frontend frameworks, Class style code are not natively supported. Like React is functional, Vue is based on plain object. No handy way to use decorater if decorater just support Class. Decorater definitely need support universal definition |
Yeah, decorators on other parts will be super handy in an add-on proposal later. I want to throw out there that making reactive variables with Example: // count.js
import {signal} from 'really-awesome-lib'
// reactive variable (signal)
@readonly
let @signal count = 0
// count is readonly outside, but still writable within the module.
setInterval(() => count++, 1000)
// main.js
import {createEffect} from 'really-awesome-lib'
import {count} from './count.js'
// This automatically re-runs any time `count` changes (dependency-tracking reactivity).
// The reactive implementation tracks any signals accessed within the function (dependencies)
// in order to re-run the function when the signals change.
createEffect(() => {
console.log('count:', count)
})
// later
count += 2 // readonly throws an error, count is not writable outside the module where it came from. |
Closing as a duplicate of #306 |
Currently the decorators proposal specifies decorators which can be applied to classes and class methods/properties. I would like to explore an extension to this proposal whereby one could apply a function to any definition (variable, constant, parameter) using the decorator syntax:
Motivation
The motivation to having this extension to the decorator proposal would be cases where you would like to run a function to validate the value assigned. This is particularly useful for runtime type schemes or data normalization.
These examples are not just contrived, but rather are very practical. Allow me to make a case.
Imagine a user-land runtime type system where each type was simply a function which validated input according to that type or threw an
TypeError
. Such a runtime type system could leverage decorator syntax to annotate the implementation with types and improve the type-safety of a codebase. Furthermore, user-land optimization tooling may be built which may do static analysis of the source code to determine where these runtime types may be safely removed from the transpiled output. This sort of source code not only renders itself as more safe, but more strict by nature; making JavaScript more correct by means of a declarative API (using decorators).Conclusion
The use-cases that come from allowing decorators to be used in more definition syntaxes are useful. We have an opportunity to add a lot of value to the developer by this extension. However, more discussion is needed to identify shortcomings and potential problematic cases.
The text was updated successfully, but these errors were encountered: