Как определить частную собственность при реализации интерфейса в TypScript?

Я использую TypeScript в своем проекте, и я столкнулся с проблемой. Я определяю такой интерфейс:

interface IModuleMenuItem {
    name: string;
}

Я хочу создать класс, который реализует этот интерфейс, но я хочу, чтобы имя было приватным свойством:

class ModuleMenuItem implements IModuleMenuItem {
    private name: string;
}

Я получаю следующую ошибку:

Класс ModuleMenuItem неправильно реализует интерфейс IModuleMenuItem. Имя свойства является приватным в модуле ModuleMenuItem, но не в типе IModuleMenuItem.

Как я могу определить свойство как личное или защищенное при реализации интерфейса?

Ответ 1

Интерфейсы определяют "публичные" контракты и, как таковые, не имеет смысла иметь protected или private модификатор доступа на интерфейсах, которые более напоминают, позволяют называть его, детали реализации. Таким образом, вы не можете делать то, что хотите, с помощью интерфейса.

Если вы хотите сделать свойство доступным только для чтения для потребителей, но переопределяемым в подклассе, вы можете сделать что-то вроде этого:

interface IModuleMenuItem {
     getName(): string;
}

class ModuleMenuItem implements IModuleMenuItem {
    private name;

    public getName() {
        return name;    
    }

    protected setName(newName : string) {
        name = newName;
    }
}

Я думаю, что в TypeScript 2.0 (еще не до конца) вы сможете использовать модификатор readonly access, если вы были после поля readinly с инициализацией - https://basarat.gitbooks.io/typescript/content/docs/types/readonly. HTML

interface IModuleMenuItem {
     readonly name : string;
}

class ModuleMenuItem implements IModuleMenuItem {
    public readonly name : string;

    constructor() {
        name = "name";
    }
}

Ответ 2

Я думаю, вы можете сделать это так

interface IModuleMenuItem{
    name: string
}

class ModuleMenuItem implements IModuleMenuItem {
    private _name: string;
    constructor() {
    _name = "name";
    }

    get name(){
    // your implementation to expose name
    }

    set name(value){
    // your implementation to set name         
    }
 }

Ответ 3

Единственный способ, которым вы можете иметь внутреннее состояние и назначить ему интерфейс вместо класса и сделать это состояние приватным

class A{
  private state:IA = ...
}