在Typescript中实现接口时如何定义私有属性?

uubf1zoe  于 2023-01-10  发布在  TypeScript
关注(0)|答案(6)|浏览(454)

我在我的项目中使用TypeScript时遇到了一个问题。我正在定义一个如下所示的接口:

interface IModuleMenuItem {
    name: string;
}

我想创建一个从这个接口实现的类,但是我希望名称是一个私有属性,如下所示:

class ModuleMenuItem implements IModuleMenuItem {
    private name: string;
}

我收到以下错误:
类ModuleMenuItem未正确实现接口IModuleMenuItem。属性名称在类型ModuleMenuItem中是私有的,但在类型IModuleMenuItem中不是。
在实现接口时,如何将属性定义为private或protected?

7z5jn7bk

7z5jn7bk1#

接口定义了“公共”契约,因此在接口上使用protectedprivate访问修饰符是没有意义的,我们称之为实现细节,因为这个原因,你不能对接口做任何你想做的事情。
如果你想让属性对使用者只读,但在子类中可以重写,那么你可以这样做:

interface IModuleMenuItem {
     getName(): string;
}

class ModuleMenuItem implements IModuleMenuItem {
    private name;

    public getName() {
        return name;    
    }

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

我认为在TypeScript2.0(尚未发布)中,如果您在初始化时只读字段-https://basarat.gitbooks.io/typescript/content/docs/types/readonly.html之后,您将能够使用readonly访问修饰符

interface IModuleMenuItem {
     readonly name : string;
}

class ModuleMenuItem implements IModuleMenuItem {
    public readonly name : string;

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

6yjfywim2#

我想你可以这样做

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         
    }
 }
kkih6yb8

kkih6yb83#

如果类中有私有字段,则需要为该字段引入setter和get方法,如下所示:

export class Model {
    private _field: number;

    get field(): number {
        return this._field;
    }

    set field(value: number) {
        this._field= value;
    }
}

然后像往常一样创建接口(我们不能对接口字段使用private修饰符),如下所示:

export interface IModel {
 field: number;
}

然后将其实现到我们的类中,如下所示:

export class Model implements IModel {
...
}

TypeScript将理解此模型在接口中正确实现,因为我们已经引入了set和get方法。

vxqlmq5t

vxqlmq5t4#

拥有内部状态并将接口分配给它而不是类并使该状态私有的唯一方法

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

bis0qfac5#

作为Syntax响应的补充,不需要包含setter,只需要getter方法,例如,这可以用于在初始化时设置的只读变量,尽管我认为在这种情况下使用readonly修饰符更好。

interface IModuleMenuItem
{
    name: string;
}

class ModuleMenuItem implements IModuleMenuItem{
    private name$: string;

    constructor(name: string)
    {
        this.name$ = name;
    }

    public get name()
    {
        return this.name$;
    }
}
9avjhtql

9avjhtql6#

请改用抽象类。
合成胜于继承。

interface AppInterface {
   app: express.Application
   port: string | number
}

abstract class AbstractApp implements AppInterface {
    app: express.Application
    port: string | number
    constructor(){
        this.app=express()
        this.port=8080
    }
    
    protected defaultMiddlewares(): void {}
}     

class App extends AbstractApp {
    constructor() {
        super()
    }

    protected defaultMiddlewares(): void {
        this.app.use(express.json())
    }
}

相关问题