Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upPrivate named instance fields #30829
Conversation
This comment has been minimized.
This comment has been minimized.
msftclas
commented
Apr 9, 2019
•
b242db5
to
f2c5233
This comment has been minimized.
This comment has been minimized.
|
Amazing achievement! Are the helpers (that would include modifications to tslib) |
This comment has been minimized.
This comment has been minimized.
|
@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. |
This comment has been minimized.
This comment has been minimized.
Sadly, they are not. A paired PR against |
This comment has been minimized.
This comment has been minimized.
Neuroboy23
commented
Apr 17, 2019
|
@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. |
This comment has been minimized.
This comment has been minimized.
G-Rath
commented
May 30, 2019
•
|
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 |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
G-Rath
commented
May 30, 2019
|
@ljharb fair enough - so then I assume TS is aiming to deprecate & remove the |
This comment has been minimized.
This comment has been minimized.
robpalme
commented
May 30, 2019
|
@G-Rath Your question on the future of TypeScript's keyword |
This comment has been minimized.
This comment has been minimized.
G-Rath
commented
May 30, 2019
This comment has been minimized.
This comment has been minimized.
septs
commented
May 31, 2019
|
"private field" decorator "private" only? class Sample {
private #field: number = 1;
} |
This comment has been minimized.
This comment has been minimized.
robpalme
commented
Jun 18, 2019
|
@rbuckton has re-landed the refactoring of class properties. The next step is to rebase this PR. |
This comment has been minimized.
This comment has been minimized.
Aqours
commented
Jun 21, 2019
|
Does |
This comment has been minimized.
This comment has been minimized.
|
@Aqours no, |
This comment has been minimized.
This comment has been minimized.
|
The rebase is in progress and we're expecting to update soon! |
This comment has been minimized.
This comment has been minimized.
|
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! |
This comment has been minimized.
This comment has been minimized.
|
That is actually really weird. Are you sure that it's not just picking up the output |
f2c5233
to
a9cb10e
This comment has been minimized.
This comment has been minimized.
|
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
This comment has been minimized.
This comment has been minimized.
mikeconley12
commented
Dec 29, 2019
•
|
Hi! I think #private fields can reduce flexibility of TypeScript (and JavaScript). // 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?
} |
This comment has been minimized.
This comment has been minimized.
|
@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.
I recommend seeing discussion at tc39/proposal-class-fields. ES private fields are a JS feature, already implemented in Chrome, Node, Babel, and (soon) Safari. |
This comment has been minimized.
This comment has been minimized.
|
Where is the plan to implement private methods? I want to use it on TS like Babel. |
This comment has been minimized.
This comment has been minimized.
|
I don't know when it's planned, but we've started writing the code and the
feature is relatively straightforward to implement now that instance fields
are in.
For now, maybe using arrow functions could be a good workaround.
…On Sun, Dec 29, 2019, 1:42 PM falsandtru ***@***.***> wrote:
Where is the plan to implement private methods? I want to use it on TS
like Babel.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#30829?email_source=notifications&email_token=ABDZJFL5T6756IQQDMAFZQLQ3CSLJA5CNFSM4HEQ7A42YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHY7X4Q#issuecomment-569506802>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABDZJFPT7RWMCXLTI7RQ2BDQ3CSLJANCNFSM4HEQ7A4Q>
.
|
This comment has been minimized.
This comment has been minimized.
|
A non-arrow function, stored outside the class and assigned to the private field, would be a bit closer in semantics. |
This comment has been minimized.
This comment has been minimized.
|
Thanks. I'm not sure what is unimplemented or not but looks like parameter properties are not supported for ES private fields (may have to consider syntax compatibility with ES). class C {
constructor(#prop: number) {
}
}I think we need the place like a separated issue to manage these considerations.
|
This comment has been minimized.
This comment has been minimized.
zhuravlikjb
commented
Dec 30, 2019
|
@falsandtru See #31670 for the discussion of 'private' vs '#'. |
This comment has been minimized.
This comment has been minimized.
|
It is helpful, thanks. |
This comment has been minimized.
This comment has been minimized.
We have no plans to implement |
This comment has been minimized.
This comment has been minimized.
|
I read #31670 (comment) but static fields are not referred. What about static private fields? Babel already implemented. |
This comment has been minimized.
This comment has been minimized.
mikeconley12
commented
Dec 31, 2019
@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 :) |
This comment has been minimized.
This comment has been minimized.
|
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>.
|
This comment has been minimized.
This comment has been minimized.
littledan
commented
Dec 31, 2019
|
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 |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
littledan
commented
Dec 31, 2019
|
@mheiber What do you mean by privacy hills? |
This comment has been minimized.
This comment has been minimized.
|
I meant "privacy holes." Autocorrect got me! |
This comment has been minimized.
This comment has been minimized.
littledan
commented
Dec 31, 2019
•
|
I'm not aware of any privacy holes in the main design. There may be other hacks that just work on this transform, though. |
This comment has been minimized.
This comment has been minimized.
Jamesernator
commented
Jan 2, 2020
•
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 },
) {}
} |
This comment has been minimized.
This comment has been minimized.
avonwyss
commented
Jan 2, 2020
|
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 |
This comment has been minimized.
This comment has been minimized.
mbrowne
commented
Jan 3, 2020
|
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 comment has been minimized.
This comment has been minimized.
kokushkin
commented
Jan 23, 2020
|
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. |
This comment has been minimized.
This comment has been minimized.
mbrowne
commented
Jan 24, 2020
|
@kokushkin Obviously |
This comment has been minimized.
This comment has been minimized.
hax
commented
Jan 27, 2020
This is not true. See my previous comment. |
This comment has been minimized.
This comment has been minimized.
mbrowne
commented
Jan 27, 2020
|
@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. |
This comment has been minimized.
This comment has been minimized.
jkrems
commented
Jan 27, 2020
•
Maybe you meant |
This comment has been minimized.
This comment has been minimized.
mbrowne
commented
Jan 27, 2020
|
@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: |

mheiber commentedApr 9, 2019
•
edited
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: