Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upPrivate named instance fields #30829
Conversation
b242db5
to
f2c5233
|
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
|
Thanks for your suggestion, @DanielRosenwasser: the completions were picking up the JS output. I added an |
a9cb10e
to
36a1648
36a1648
to
d2adc3c
71c384a
to
afcc88c
We have no plans to implement |
|
I read #31670 (comment) but static fields are not referred. What about static private fields? Babel already implemented. |
@mheiber Thank you for the answer! But still, is there any way to "hack" the #private properties? I understand that the hack will be a bad practice. But I'm curious :) |
|
Not that I know of. For the private fields transformation for targets without native support: you can see break the privacy by fiddling with the WeakMap prototype unless it's frozen.
…________________________________
From: mikeconley12 <notifications@github.com>
Sent: Tuesday, December 31, 2019 12:29:07 PM
To: microsoft/TypeScript <TypeScript@noreply.github.com>
Cc: Max Heiber <max.heiber@gmail.com>; Mention <mention@noreply.github.com>
Subject: Re: [microsoft/TypeScript] Private named instance fields (#30829)
@mikeconley12<https://github.com/mikeconley12> , this is a good question. The short answer is that you cannot access the private field from another-module.ts in your example. There was a trade-off here between 'hard privacy' and expressiveness. In your example, perhaps a WeakMap or Symbol might work better.
Hi!
I think #private fields can reduce flexibility of TypeScript (and JavaScript).
For example, how can I access #private fields from prototype methods in the following example:
// greeter.ts
class Greeter {
#name: string;
constructor(name: string) {
this.#name = name;
}
greet() {
console.log(`hello ${this.#name}`);
}
}
// another-module.ts
Greeter.prototype.myAwesomeGreet = function() {
// how can I access this.#name from here?
}
I recommend seeing discussion at tc39/proposal-class-fields<https://github.com/tc39/proposal-class-fields>. ES private fields are a JS feature, already implemented in Chrome, Node, Babel, and (soon) Safari.
@mheiber<https://github.com/mheiber> Thank you for the answer!
But still, is there any way to "hack" the #private properties?
I understand that the hack will be a bad practice. But I'm curious :)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<#30829?email_source=notifications&email_token=ABDZJFMDVTDFLDWVKS5MAETQ3M3JHA5CNFSM4HEQ7A42YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEH4E7RY#issuecomment-569921479>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ABDZJFLCSTUM26I3UT2LV53Q3M3JHANCNFSM4HEQ7A4Q>.
|
|
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. |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.


Private-Named Instance Fields
This PR implements the tc39 class fields proposal for TypeScript. It includes:
PR merge checklist
@targets to conformance tests esp this oneExample:
ts
js
This PR lead to the following related work by the team:
Babel issues reported:
V8 issues reported:
Related TS PRs:
This PR includes work by the following engineers: