【问题标题】:In typescript, how to export the type of a private class without exporting class itself在打字稿中,如何在不导出类本身的情况下导出私有类的类型
【发布时间】:2018-08-29 18:01:34
【问题描述】:

我有一个模块,其中公共类的公共方法创建并返回私有类的新实例。要求是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'.

我的目标是只导出私有类的“类型”,而不让使用模块的代码直接实例化它。例如

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 导出类型不起作用?
  • 如何在不暴露模块外部私有类的情况下导出类型?

【问题讨论】:

  • MyClassPrivateHelper 类型到底是什么? MyClassPrivateHelper 在上面的代码中没有公共成员。
  • MyClassPrivateHelper 创建一个接口。导出并改用它。
  • 我无法复制您示例中的错误。你使用的是最新版本的 TypeScript 吗?
  • @Behrooz 如果你启用declaration emitting 就会发生这种情况
  • @estus 我更新了代码以添加一个公共方法来显示使用情况。 @Behrooz 我正在使用 TS 版本 2.7.2。正如提香所说,我的tsconfig 中有"declaration": true

标签: typescript typescript-typings


【解决方案1】:

您应该创建一个接口并将其导出:

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();

【讨论】:

  • 应该被接受为正确答案
【解决方案2】:

为什么使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 2018-05-24
    • 1970-01-01
    • 2022-01-22
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多