Skip to content
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

Suggestion: Explicit interface implementation #2071

Closed
Anupheaus opened this issue Feb 18, 2015 · 5 comments
Closed

Suggestion: Explicit interface implementation #2071

Anupheaus opened this issue Feb 18, 2015 · 5 comments
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Suggestion An idea for TypeScript

Comments

@Anupheaus
Copy link

I'd like to request that either private members be able to fulfill interface contracts or a new type of member that is designed to fulfill contracts but are not exposed publicly.

At the moment, any interface implemented on a class has to expose all members of that interface publicly, however, I'd like to be able to implement an interface such as IDropTarget that has members such as DraggableEntered(), DraggableLeft(), etc that are not exposed publicly - I mean, I'd like to be able to pass the class instance as an IDropTarget to somewhere and those methods be used, but I'd rather not see them in intellisense when accessing the members of that instance - they just aren't necessary for public exposure.

Hope this makes sense and no-one else has yet suggested this, I did do a search but I didn't find anything like this.

@danquirk
Copy link
Member

If I'm understanding correctly it seems like maybe the better solution is to be able to use annotations/decorators to signal to an editor that certain members should be hidden, akin to the behavior we have today that makes Object's members not show up in Intellisense, ex:

var x = {}
x.toString(); // no error, but no . completion off x suggests toString

Would that do what you want?

@Anupheaus
Copy link
Author

Yes it would, but how would you know if the property were to be visible or not, I mean typically toString is public, but I imagine there is a list or even hard coded that toString does not appear in the intellisense, and so 1) you wouldn't have my properties on that list and 2) I might in other cases want a public member to be exposed and fulfil an interface contract.

I would simply suggest that private members can also fulfill a contract (in my head, that would be the simplest thing to do, but I don't really know how it works under the hood). There must be some check to say "this class has x interface implemented, does it expose all the members to x interface publicly?" I'd just change that to be "this class has x interface implemented, does it contain all the members to x (publicly or not)?"

@Anupheaus
Copy link
Author

Having thought about my comment for a few seconds, I've then thought that actually, it kinda breaks the whole privacy aspect of a private member (even though I know if I were to write (<any>myObject).myPrivateMember it would actually access it because of the underlying javascript). But private should be private and therefore, implementing an interface should not break privacy (I imagine this is the reason why explicit interface implementation in c# does not use private members to fulfull interface contracts). Therefore I propose something either similar to c#:

module myModule {
    export myInterface {
        myMember(): void;
    }

    export class myClass implements myInterface {
        myInterface.myMember(): void {
            // do myMember stuff
        }
    }
}

or use a new keyword, perhaps called "explicit", for example:

module myModule {
    export myInterface {
        myMember(): void;
    }

    export class myClass implements myInterface {
        explicit myMember(): void {
            // do myMember stuff
        }
    }
}

myMember would not be shown in intellisense on any myClass instance, but it would be in intellisense for any myInterface instance and it isn't causing the private keyword to be any less private.

@danquirk
Copy link
Member

Yes it would, but how would you know if the property were to be visible or not, I mean typically toString is public, but I imagine there is a list or even hard coded that toString does not appear in the intellisense, and so 1) you wouldn't have my properties on that list and 2) I might in other cases want a public member to be exposed and fulfil an interface contract.

The point is you would manually annotate properties you wanted to not show up, ex something like #1557.

C#'s private means different things than TypeScript because TypeScript uses structural typing rather than nominal typing. I cannot see modifying existing language semantics or keywords specifically for what is ultimately an editor feature. That's why annotations seem like a better fit.

@Anupheaus
Copy link
Author

Sorry I didn't know that annotations such as those had been suggested.

After much self deliberation, I agree to your point that they would be a good fit for this. Ideally I'd like it so that it was a bit more like C# in that those members would ONLY be able to be accessed via the interface but I doubt that would be possible in JS without a hell of a lot of injected code (and even then I doubt it would be possible or at least feasible).

@danquirk danquirk added the By Design Deprecated - use "Working as Intended" or "Design Limitation" instead label Feb 19, 2015
@danquirk danquirk added the Suggestion An idea for TypeScript label Feb 19, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants