{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/10302","repository_url":"https://api.github.com/repos/Microsoft/TypeScript","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/10302/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/10302/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/10302/events","html_url":"https://github.com/Microsoft/TypeScript/issues/10302","id":170864627,"number":10302,"title":"Allow access to private class members if the 'this' type of an (extension) function is specified","user":{"login":"lhecker","id":2256941,"avatar_url":"https://avatars.githubusercontent.com/u/2256941?v=3","gravatar_id":"","url":"https://api.github.com/users/lhecker","html_url":"https://github.com/lhecker","followers_url":"https://api.github.com/users/lhecker/followers","following_url":"https://api.github.com/users/lhecker/following{/other_user}","gists_url":"https://api.github.com/users/lhecker/gists{/gist_id}","starred_url":"https://api.github.com/users/lhecker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lhecker/subscriptions","organizations_url":"https://api.github.com/users/lhecker/orgs","repos_url":"https://api.github.com/users/lhecker/repos","events_url":"https://api.github.com/users/lhecker/events{/privacy}","received_events_url":"https://api.github.com/users/lhecker/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/In%20Discussion","name":"In Discussion","color":"556b75"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Suggestion","name":"Suggestion","color":"006b75"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":7,"created_at":"2016-08-12T12:52:40Z","updated_at":"2016-08-15T14:49:11Z","closed_at":null,"body":"First of all: Please excuse me if this issue is a duplicate of some sort, but I've searched for quite some time for a similar issue or at least an answer to the following question/bug/proposal and found nothing.\r\n\r\nIf I specify that a function has a certain (customized) 'this' type I expect that the function has full access to private and protected fields of passed instances. Reason being that due to JavaScripts dynamic nature and it's capability to overwrite the `this` pointer, a function that is freestanding can still act like an extension method to a class.\r\n\r\nBelow you can find a simple JavaScript-like style of extending a existing class, which fails in TypeScript, because it strictly forbids access to private fields outside of the actual class:\r\n\r\n```ts\r\nclass MyClass {\r\n    private p: number;\r\n\r\n    constructor() {\r\n        this.p = 123;\r\n    }\r\n}\r\n\r\ninterface MyClass {\r\n    extension(p: number): void;\r\n}\r\n\r\nMyClass.prototype.extension = function (this: MyClass, p: number) {\r\n    // FAILS with:\r\n    //   error TS2341: Property 'p' is private and only accessible within class 'MyClass'.\r\n    this.p = p;\r\n}\r\n\r\nconst instance = new MyClass();\r\ninstance.extension(456);\r\n```\r\n\r\nI realize that some kind of \"official\" class extension technique will get into TypeScript sooner or later, but all of the proposals I've seen extend the actual JavaScript language with new keywords. This question/bug/proposal here though, basically does exactly the same as the existing extension proposals but within the boundaries of the JavaScript language (apart from the existing language extensions for the type checker).\r\n\r\nI thus humbly suggest to loosen this strict access control and allow us to write extension methods to at least some extend before v2.0 is finally released."},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/239821789","html_url":"https://github.com/Microsoft/TypeScript/issues/10302#issuecomment-239821789","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/10302","id":239821789,"user":{"login":"lhecker","id":2256941,"avatar_url":"https://avatars.githubusercontent.com/u/2256941?v=3","gravatar_id":"","url":"https://api.github.com/users/lhecker","html_url":"https://github.com/lhecker","followers_url":"https://api.github.com/users/lhecker/followers","following_url":"https://api.github.com/users/lhecker/following{/other_user}","gists_url":"https://api.github.com/users/lhecker/gists{/gist_id}","starred_url":"https://api.github.com/users/lhecker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lhecker/subscriptions","organizations_url":"https://api.github.com/users/lhecker/orgs","repos_url":"https://api.github.com/users/lhecker/repos","events_url":"https://api.github.com/users/lhecker/events{/privacy}","received_events_url":"https://api.github.com/users/lhecker/received_events","type":"User","site_admin":false},"created_at":"2016-08-15T14:49:10Z","updated_at":"2016-08-15T14:49:10Z","body":"> so what? are you suggesting to legalize a hack\r\n\r\nIt's not a hack because it would imply that you can do something that you couldn't do before. And yes I'm advocating for this obviously or why should I have created the issue then?\r\n\r\n> `protected` is not the same as private because protected members can be _legally_ accessed in a derived class \r\n\r\nWould you be more comfortable with the proposal if I'd edit the title to read `protected` instead of `private`?\r\n\r\n> i hear that you have problems with the size of your class\r\n\r\nYour `legallyUsingPrivateState` method is kinda bad, because it can be accessed by \"3rd party code\" to do anything with the private state. But okay... Let's assume that the method was a private one and that the `A` class always initiates the call to an extension: It still doesn't work for accessing private/protected member _functions_, which takes up the majority of my code (obviously). If you want to do that you'd have to make `PrivateMatters` a class and move those methods to it. What you might realize now is that you have the same situation as before: Your `PrivateMatters` is what `A` was before and your `A` class now is only a wrapper around `PrivateMatters` to protect it from unwanted access..."}}
{"actor":{"display_login":"lhecker"}}