0

I have a CPU-constrained project with a large number of classes and I use interfaces to minimize the number of imports I use in each module. However, I've run into some issues when declaring private methods on classes that implement their respective interfaces. Currently, I'm encountering:

index.d.ts:

interface IColony {
    // (other public properties)
    // instantiateVirtualComponents(): void;
}

Colony.ts:

export class Colony implements IColony {
    // (constructor and other methods)
    private instantiateVirtualComponents(): void {
        // (implementation)
    }
}

The issue is that TypeScript won't seem to let me declare private properties on this class. As is, tsc complains:

Error:(398, 3) TS2322:Type 'IColony' is not assignable to type 'Colony'. Property 'instantiateVirtualComponents' is missing in type 'IColony'.

I'm pretty sure that private properties and methods shouldn't be declared in the interface, but just to be safe, if I uncomment the method declaration in IColony, tsc then complains the following (among lots of other errors resulting from this):

Error:(10, 14) TS2420:Class 'Colony' incorrectly implements interface 'IColony'. Property 'instantiateVirtualComponents' is private in type 'Colony' but not in type 'IColony'.

What am I doing wrong here? Can you simply not declare private members on classes that implement an interface?

For reference, Colony.ts is here and the relevant part of index.d.ts is here.

Ben Bartlett
  • 322
  • 4
  • 14
  • Seems to work fine in the [playground](https://www.typescriptlang.org/play/). Which version of TypeScript/tsc? – jonrsharpe Jun 05 '17 at 19:22
  • 1
    Right now, the code, as is, from your question is working. I'm expecting the errors occur when you uncomment that line in the interface. You may want to show each bit of code that produces the error along with the error. – Heretic Monkey Jun 05 '17 at 19:25
  • I've added Github links to the full code. @jonrsharpe, I'm running TypeScript 2.3.3. – Ben Bartlett Jun 05 '17 at 19:28
  • You simply can't use a private member to implement a method defined in an interface. It helps if you think of an interface as the contract which other objects read to understand what they can call. If the method is private, it cannot be called by external objects, and therefore violates the contract. – Heretic Monkey Jun 05 '17 at 19:30
  • @MikeMcCaughan I might be misunderstanding what you are saying, but I'm aware that you cannot declare a method in an interface and then have the implementation be private. I'm confused about the reverse - I want to implement a private class method, but tsc seems to want the private method declared on the interface (and then complains when I do that). – Ben Bartlett Jun 05 '17 at 19:40
  • I don't understand. This question needs a [mcve](https://stackoverflow.com/help/mcve). – Alex Jun 05 '17 at 20:16
  • It seems to me you're doing it wrongly. Dependency goes in opposite direction. You should not assign IColony to Colony but vise versa. – Sofija Dec 18 '17 at 15:01

2 Answers2

2

It's because

Interfaces define "public" contracts and as such it doesn't make sense to have protected or private access modifier on interfaces, which are more of a, let's call it, implementation detail. As such you can't do what you want with an interface.

see also the original post

Ronin
  • 7,322
  • 6
  • 36
  • 54
0

You are probably doing something similar to:

function fn(): IColony { ... }

let a: Colony = fn(); // error: Type 'IColony' is not assignable to type 'Colony'...

This error occurs because you are trying to assign an instance of IColony to a variable of type Colony and it doesn't work that way (only the other way around).

If that's the case then it should be:

let a: IColony = fn();
Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299