【问题标题】:typescript package visibility (create library)打字稿包可见性(创建库)
【发布时间】:2017-06-29 09:30:07
【问题描述】:

我正在创建一个用于不同项目的打字稿库。 我想要的是只为外部发布我的类函数的一个子集,并在我的库中内部使用其他函数。

在示例中:

/* Person.ts */
export class Person{
    getName(){
        .....
        return name;
    } 
    getInfos(){

    }
}

/* People.ts */
export class People{
    ...
    setName(){
       let p = new Person();
       ...
       let n = p.getName();
       ....
    }

}

我希望我的库公开 Person getInfos() 和 People setName() 但我希望 Person getName 只能在内部访问。 也许我必须创建一个仅向外部用户公开一种方法的 Person.d.ts,但我不明白如何。

谢谢

【问题讨论】:

  • 注意People类会访问getName()方法,所以设置为private不是解决办法。

标签: angular typescript package declare


【解决方案1】:

如果您想在没有特定方法的情况下拥有包含 d.ts 文件的库,您可以执行以下操作

parson.ts

export class Person{
  /** @internal */ <== annotate field with internal flag
  private getName(){
    return name;
  }
  /** @internal */ <== annotate field with internal flag
  public getName2(){
    return name;
  }
  getInfos(){

  }
}

然后通过指定stripInternal 编译选项告诉编译器不要为具有/** @internal */ JSDoc 注释的代码发出声明

tsconfig.json

{
  "compilerOptions": {
    ...
    "declaration": true,
    "stripInternal": true, <== this option

输出应该如下

person.d.ts

export declare class Person {
  getInfos(): void;
}

所以打字稿跳过了所有用/** @internal */注释的字段,即使是public修饰符

Angular 在构建项目时使用相同的方法

【讨论】:

  • 但是People类可以访问getName方法吗?
  • 正如@Maximus 所说的in JavaScript everything is public。所以const people = new People(); (people as any).getName() 应该可以工作。我的解决方案适合编译时
  • 我知道在js中都是公开的,我有兴趣在编译时进行封装。我的目标是创建一个库并允许其他开发人员在我的类中只使用一些方法(就像我在 Java 中使用 package 修饰符一样)。我认为你的解决方案还不够
  • @Maximus 对不起,我的意思是 getName2 .. 我试试你的代码: - 如果我使用内部注释,我有一个 ts 错误(找不到名称“内部”)。我必须进口一些东西? - 如果我从这个模块外部手动创建 Person.d.ts 文件,ts 允许我也使用 person.getName2()。在我的测试中 Person.d.ts 和 person.ts 在同一个文件夹中..
  • 我不知道你是如何建立你的图书馆的。我坚持Angular Package Format v4.0 docs.google.com/document/d/…
【解决方案2】:

您必须区分编译时和运行时封装。如果您只需要编译时封装,您可以使用@trichetriche 建议的方法并将getName 声明为私有或使用@yurzui 更高级的方法。

如果您想要运行时封装,您必须使用不同的方法。如果你导出一个类,它会导出它的所有方法,因为在 JavaScript 中一切都是公开的。要隐藏某些功能,您可以在模块中创建一个函数getName,但不要公开它。您将可以使用它,但它在外面不可用:

function getName() {... return name;}

export class Person{
    getInfos(){
        return getName.call(this);
    }
}

【讨论】:

  • 在您的示例中,函数 getName 独立于 Person 类,因此无法访问私有 var 或内部方法。
  • @user1439356 getName 函数获取上下文this。您可以访问内部方法
【解决方案3】:

如果您想在内部使用 getName 并且不导出它,只需执行

/* Person.ts */
export class Person{
    protected getName(){
        return getName();
    } 
    getInfos(){

    }
}

/* People.ts */
export class People extends Person {
    ...
    setName(){
      let p = new Person();
      ...
      let n = p.getName();
      ....
    }

}

【讨论】:

  • 这仍然可以在 JS 中访问
  • 有问题吗?
  • 这取决于 OP 想要什么,运行时封装或编译时间
  • 如果方法是私有的,People类不能使用。我需要一种 "package" 方法,我的库中的所有类都可以使用它,但外部项目只使用公共方法。
  • @trichetriche,这无济于事,因为所有类都必须扩展基类才能使用protected
猜你喜欢
  • 2021-07-19
  • 1970-01-01
  • 2020-03-02
  • 2016-06-22
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2019-04-18
相关资源
最近更新 更多