-
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
context.access
API implementation feedback.
#494
Comments
|
Given our release cadence and the timing of the upcoming TC39 plenary, the TypeScript 5.0 beta will likely ship with Stage 3 Decorators support, with the exception of With how the TS emit for Stage 3 Decorators works today, enabling |
After some thought I agree with these changes overall, I do think it would be a better DX to not use I am not sure if I'll be able to attend the January plenary (I just had COVID and have been catching up on a decent amount of work) but I support this being presented to the committee. |
I have raised this problem before but it looks like the designer doesn't like this idea. I also worry that this change increases memory usage. class T {
@f accessor x = expr
}
function f(context) {
// every `new T` creates a new context.access.get/set
} |
@Jack-Works by the designer, do you mean me? Just confused because I'm the current champion/designer and I just commented that I support the change, sorry if I'm misunderstanding 😅 re: memory usage, the design would not require a new |
It would still require creating a new one every time, unless we wanted one decorator to be able to add properties to it, and have later decorators see those - I doubt we want that communications channel. |
Hmm, good point, but then that would be the same with the current design as well though. Still I think it's better that it's unbound, there's the parallel to Reflect, and maybe one less reference to store? |
Yes, I tend to agree - i agree the performance/new object story is the same either way, and adding |
Very good point. I don't think we should allow shared mutable instances between decorators like this. But given that you'd only have to create one for each [decorator, decorated accessor] tuple, I don't think that's particularly a high cost. Furthermore engines are free to lazily create this |
I don’t think it needs to be a getter - we don’t need to specify unobservable optimizations. |
This is an incorrect assumption. A new |
Oh when this design ( |
Searching leads me to #452 or #450 or #310 (comment), but none of those seem to be discussing the possibility of first-arg get/set functions :-/ |
I do think we may have discussed this in meetings, which may be why it isn't in the issues. I did previously think that the |
If we froze the context and access objects, and then specified that we always reused the same frozen object for a given application of a decorator, would anything break? |
You need a new access object per {field x instance} anyway. Freezing it may be more costly - that might depend on the average number of decorators per decorated field. |
You wouldn't need a new one if the functions take the instance as either the receiver or an argument. |
These changes have been merged into the spec, so I'm going to close this issue. |
Can someone else's decorator override my context's |
TypeScript has been working on an implementation of the Stage 3 decorators proposal, and have been evaluating a number of user scenarios leveraging the current specification text. As part of this, we have found that the current design for the
context.access
object's API has a somewhat poor DX, and is missing a necessary capability (access.has
).context.access.get
andcontext.access.set
DX ConcernsThe API for the
get
andset
methods oncontext.access
currently require you to pass thethis
context via.call
:I believe this was intended to mimic the behavior for method/auto-accessor replacement, i.e.:
However, this may be the wrong behavior to mimic. The
.call
behavior is a necessity for method replacement, since both the function you are replacing and the function you replace it with must pass alongthis
as thethis
-binding. However,access.get
andaccess.set
don't have that requirement, and more closely resembleReflect.get
/Reflect.set
andWeakMap.prototype.get
/WeakMap.prototype.set
.We have found the current metaphor, emulating replacement, is far more confusing.
context.access.has
MethodAnother issue we've found is that, while
context.access.get
and.set
are extremely valuable for some scenarios where private member access is required, the fact that there is no imperative mechanism to emulate#x in obj
viacontext.access
can make it difficult for some of these scenarios to perform pre-emptive validation.Having such an API would also more strongly inform the correct metaphor for
.get
and.set
, in that you are far less likely to expect to docontext.access.has.call(obj)
, given that there is no direct corollary to that in the method replacement metaphor.Suggested Changes
As such, we would suggest the following changes to the
context.access
API to improve the development experience:context.access.get.call(target)
tocontext.access.get(target)
context.access.set.call(target, value)
tocontext.access.set(target, value)
context.access.has(target)
Or, in TypeScript parlance:
The text was updated successfully, but these errors were encountered: