-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Private named instance fields #30829
Private named instance fields #30829
Conversation
b242db5
to
f2c5233
Compare
Amazing achievement! Are the helpers (that would include modifications to tslib) |
@mihailik thanks! As far as I know, the helpers work the same way. Is any additional work required to get the helpers into tslib? I was hoping the syncing was semi-automated. |
Sadly, they are not. A paired PR against |
@weswigham: I have asked our IP team to set up a fork of the tslib repo. @joeywatts and @mheiber: Will you take a look at this other repo? I think it will be an easy mod. |
Forgive me if this is obvious, but I've look around on the issues and couldn't see this covered anywhere: Is there any particular reason why we can't do Would there be any chance of getting that syntax supported? In my eyes it'd give us the best of both worlds, as then all class properties can maintain their indentation level, along with making refactoring easy for people like me who prefix all our private properties with I mean you could pretty much just use a global find-and-replace using Also, could someone confirm for me if its planned for TS somewhere down the line to transform |
@ljharb fair enough - so then I assume TS is aiming to deprecate & remove the |
@G-Rath Your question on the future of TypeScript's keyword |
"private field" decorator "private" only? class Sample {
private #field: number = 1;
} |
@rbuckton has re-landed the refactoring of class properties. The next step is to rebase this PR. |
Does |
@Aqours no, |
The rebase is in progress and we're expecting to update soon! |
I noticed an issue with our Language Service changes. Type inference and red underlines work correctly, but autocomplete is borked. Steps to reproduce:In a class with private field #foo#, start typing Actual behavior:Autocomplete completes incorrectly (see screenshot). It is actually completing with secret variables we use in the transformation Expected behavior:Autocomplete completes as Advice welcome on how to fix autocomplete in this PR! |
That is actually really weird. Are you sure that it's not just picking up the output |
f2c5233
to
a9cb10e
Compare
Thanks for your suggestion, @DanielRosenwasser: the completions were picking up the JS output. I added an |
a9cb10e
to
36a1648
Compare
36a1648
to
d2adc3c
Compare
71c384a
to
afcc88c
Compare
Private fields are deliberately designed to be not hackable: strong encapsulation is a core design goal. I'd recommend strongly against manipulating WeakMap's prototype for this purpose--it won't hold up when you later upgrade to native private fields (which have better performance). If you want hackable privacy, you can continue to use the TypeScript |
fwiw, I agree that the hack is a bad idea. Wouldn't want the hack to be a secret, though, since it's good to know that the privacy of the transformed code is not absolute, barring control over the WeakMap prototype. @littledan, are there other |
@mheiber What do you mean by privacy hills? |
I meant "privacy holes." Autocorrect got me! |
I'm not aware of any privacy holes in the main design. There may be other hacks that just work on this transform, though. |
The feature is pretty popular, I imagine a lot of places won't adopt private fields primarily for this reason. Has a similar feature been considered for proposing at TC39? e.g.: class Point {
constructor(#x: number, #y: number) {}
} And for public fields maybe allow using class Image {
constructor(
this.data: ImageData, // Simple parameter
{
height: this.height,
width: this.width /* in destructuring */
}: { width: number, height: number },
) {}
} |
Given that the This would allow to implement a version which also works without WeakMap support (e.g. IE <= 10), or for anyone who wants to use a different mechanism, such as with non-enumerable properties or |
In case anyone else is wondering the same thing I was, it looks like the first production release to include this will be version 3.8, scheduled for sometime in February: |
This looks ridiculous and disrupt developer experience with the language, especially for newers) Please, don't do it. This is feature for Typescript 4, not for 3.8, where we can break backward compatibility. Or, at least either "private" or "#" must be deleted in Typescript 4. |
@kokushkin Obviously |
This is not true. See my previous comment. |
@hax You're right, I didn't mean to mislead anyone, just should have written more carefully... I was trying to emphasize that this isn't just an early-stage proposal that TypeScript decided to implement on their own. I should have said it's a proposed standard that's very near the final stage of the standardization process, with private fields now enabled by default in Chrome, Firefox, and node. |
Maybe you meant |
@jkrems Ah yes, thanks for the correction. The public fields part of the proposal is enabled by default in Firefox...next step will probably be to add private fields behind a flag. Implementation status is periodically updated here: |
A question about the downlevel emit - to use this feature I have to target ES2015. But that will mean classes remain as classes, which breaks IE11. And yet IE11 supports Is IE11's If I could suppress the error somehow... #29950 |
…e fixes Summary: * Add private-named instance fields. Ex: `x.#name;`. [1] * Support type-only imports and exports. [2] * Improve the detection of conditional expressions `a ? b : c`. Allow multiple lines. * Add rules of round brackets `()` to correct the highlighting of pairs of brackets. [3] [1] microsoft/TypeScript#30829 [2] microsoft/TypeScript#35200 [3] https://unix.stackexchange.com/questions/527268/kate-18-12-3-no-longer-shows-matching-parenthesis-for-typescript Reviewers: #framework_syntax_highlighting, dhaumann, cullmann Reviewed By: #framework_syntax_highlighting, cullmann Subscribers: kwrite-devel, kde-frameworks-devel Tags: #kate, #frameworks Differential Revision: https://phabricator.kde.org/D27692
The implementation could use a single WeakMap per module, instead of one WeakMap per property. It think it may be more efficient. Maybe I missed it: is there a specific reason it needs to be one WM per property? |
At the least you’d need one for statics, and one for instances - but actually, it wouldn’t necessarily be more efficient, since you’d need a containing object to look up the individual fields in - and for functions, you’d have to be very careful not to expose the containing object as the receiver. |
Ah, right! I take that back, because for each instance, we'd need that accompanying object, which means O(n) instead of O(1) mem use for storage containers for the key-value pairs, where |
@trusktr FYI, there's also this issue: https://github.com/tc39/proposal-class-fields/blob/master/PRIVATE_SYNTAX_FAQ.md#how-can-you-model-encapsulation-using-weakmaps. Babel works around this by creating a separate WeakMap for each field. |
Private-Named Instance Fields
This PR implements the tc39 class fields proposal for TypeScript. It includes:
PR merge checklist
@target
s to conformance tests esp this oneExample:
ts
js
This PR lead to the following related work by the team:
Babel issues reported:
.name
incorrect for private fields babel/babel#10175V8 issues reported:
Related TS PRs:
This PR includes work by the following engineers: