在typescript中,如何在不导出类本身的情况下导出私有类的类型

时间:2018-03-20 19:11:17

标签: typescript typescript-typings

我有一个模块,其中公共类的公共方法创建并返回私有类的新实例。要求是MyClassPrivateHelper必须仅由MyClass实例化。

class MyClassPrivateHelper {
    constructor(private cls: MyClass) {
    }

    public someHelperMethod(arg): void {
        this.cls.someMethod();
    }
}
export class MyClass {
    public createHelper(): MyClassPrivateHelper {  // error here
        return new MyClassPrivateHelper(this);
    }

    public someMethod(): void {
        /**/
    }
}

通过这种安排,TypeScript报告错误:

[ts] Return type of public method from exported class has or is using private name 'MyClassPrivateHelper'.

我的目标是只导出私有类的“类型”,而不让代码消耗代码直接实例化它。 e.g。

const mycls = new module.MyClass();

// should be allowed
const helper: MyClassPrivateHelper = mycls.createHelper();

// should not be allowed
const helper = new module.MyClassPrivateHelper();

我尝试使用typeof这样没有成功。

export type Helper = typeof MyClassPrivateHelper

也许我不理解“typeof”是如何工作的。我的问题是:

  • 为什么使用typeof导出类型不起作用?
  • 如何在不暴露模块外部的私有类的情况下导出类型?

2 个答案:

答案 0 :(得分:4)

您应该创建一个界面并导出:

export interface IMyHelper {
   someHelperMethod(arg): void;
}

然后让Helper实现:

class MyClassPrivateHelper implements IMyHelper {
    constructor(private cls: MyClass) {
    }

    public someHelperMethod(arg): void {
        this.cls.someMethod();
    }
}

公共类将返回接口

export class MyClass {
    public createHelper(): IMyHelper { 
        return new MyClassPrivateHelper(this);
    }

    public someMethod(): void {
        /**/
    }
}

辅助工具从外部再次被其界面引用:

const helper: IMyHelper = mycls.createHelper();

答案 1 :(得分:1)

  

为什么使用typeof导出类型无效?

export type MyInterface = typeof MyClassPrivateHelper

在此示例中,MyInterface是构造函数的类型,但是您想导出该构造函数可以产生的实例的类型。

  

如何在不暴露模块外部私有类的情况下导出类型?

赞:

export type MyInterface = InstanceType<typeof MyClassPrivateHelper>

InstanceType在这里简要描述:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

或者,我发现以下内容也适用:

type Interface<T> = { [P in keyof T]: T[P] }
export interface MyInterface extends Interface<MyClassPrivateHelper> {}

Interface类型基本上从T复制所有公共属性,然后我们用它们来声明一个新接口。

有关更多详细信息,请参见https://github.com/Microsoft/TypeScript/issues/471#issuecomment-381842426