Angular Typescript如何从嵌套对象Getter返回类函数引用

Angular Typescript如何从嵌套对象Getter返回类函数引用,angular,typescript,getter,es6-class,Angular,Typescript,Getter,Es6 Class,我正在编写一个服务类,其中包含一组实用函数。不是将所有函数公开为公共函数,而是将这些函数连接到一系列公共对象中,这些对象旨在为访问它们提供逻辑流。下面是一个例子: class MyUtilService { public exposedObject = { get prop1() { return this.utilFunction1; }, get prop2() { return this

我正在编写一个服务类,其中包含一组实用函数。不是将所有函数公开为公共函数,而是将这些函数连接到一系列公共对象中,这些对象旨在为访问它们提供逻辑流。下面是一个例子:

class MyUtilService {
    public exposedObject = {
        get prop1() {
            return this.utilFunction1;
        },
        get prop2() {
            return this.utilFunction2;
        }
    };

    private utilFunction1() {//...}
    private utilFunction2() {//...}
}
问题是,getter中的
this
对象引用的是
exposedObject
,而不是类(正如预期的那样)。目标是在应用程序的其他地方访问这些函数,如下所示:

myUtilService.exposedObject.prop1() // Want this to execute utilFunction1
这里的另一个要求是在使用时维护
utilFunction1
中的键入信息。我以前使用过
.bind(this)
而不是getter,但这阻止了任何输入信息的传递。
对象也会发生同样的情况。defineProperty
。你有没有想过我该怎么做

注意:使用TS 2.5.x和Angular 5.x

编辑: 我补充了一些额外的信息,因为这个问题的核心在我最初的帖子中并不清楚。当一个私有函数使用服务中的另一个函数时,就会出现主要问题。考虑这个代码:

class MyUtilClass {
    public exposedObject = {
        prop1: this.utilFunction1
    };

    private utilFunction1() {
        this.utilFunction2();
    }
    private utilFunction2() {//...}
}

// Want this to execute utilFunction1 which executes utilFunction2
someService.exposedObject.prop1()

utilFunction2在
utilFunction1
内部使用,但当调用
myUtilClass.exposedObject.prop1()
时,
this.utilFunction2
未定义,因为
this
上下文来自调用方(同样,正如预期的那样)。这可以通过
prop1:This.utilFunction1.bind(This)
来克服,但随后会丢失函数的键入信息。这是个难题。这就是为什么我选择了嵌套getter,但是它在
这个
上下文中有它自己的问题。

考虑到您试图实现的目标,这应该适合您

class MyUtilService {
    public exposedObject = {
        prop1:this.prop1,
        prop2:this.prop2
    }
    private get prop1(){
        return this.utilFunction1();
    }
    private get prop2() {
        return this.utilFunction2();
    }

    private utilFunction1() {}
    private utilFunction2() {}
}

let utilityservice = new MyUtilService();
utilityservice.exposedObject.prop2;

TypeScript是真正的JavaScript。您的类在执行之前将转换为javascript函数。 例如,当您使用get或set关键字定义函数时,您不使用():

每个对象都有自己的上下文
this

我甚至不相信你所期望的是可能的。我和你们班的同学玩了一会儿。我能够将outter contex传递给内部对象,但女贞方法仍然可以作为公共方法使用。似乎所有类型脚本类都是这样,就像js一样,所有成员都是公共的。我是TypeScript新手,只是想展示原型(TS和JS)与clasic OOP有多大的不同

class MyUtilService {
  public exposedObject: Object;
  constructor() {

    class ExposedObject {
      constructor(private parent: MyUtilService) {}
      get prop1() {
          console.log(this);
          return this.parent.utilFunction1();
      }
      get prop2() {
          return;
      }
    }
    this.exposedObject = new ExposedObject(this);
  }


  private utilFunction1() { return 'uf'; }
  private utilFunction2() {}
}

const u = new MyUtilService();
const value = u.exposedObject.prop1;
console.log(value);
console.log(u.utilFunction1());

好吧,我就是这样解决这个问题的。使用与前面相同的示例:

let _otherService: OtherService;

export class MyUtilClass {

    constructor(private otherService: OtherService) {
        _otherService = otherService;
    }

    public exposedObject = {
        prop1: utilFunction1
    };
}

function utilFunction1() {
    utilFunction2();
}
function utilFunction2() {
    _otherService.doSomething();
}

我最终在主类的之外定义了实用函数。然后,
这个
就不再有问题了。这些函数可以相互使用,我甚至可以通过构造函数公开注入的服务以供引用(可能是因为服务在这些函数中的任何一个可用之前被实例化)。类型信息也通过exposedObject继承。谢谢大家的建议

如果某些属性访问器可以公开这些函数,为什么不首先公开它们呢?难道你不能返回函数.bind(这个)?@PatrickRoberts是的,它们在技术上是公开的,因为在运行时它只是javascript,你可以通过myService['myPrivateFunction']()绕过TS编译器。但这在某种程度上规避了最初使用TS的全部目的。在我的例子中,我不想公开所有函数,因为将它们分离到一个嵌套对象中可以更清楚地说明如何使用它们。直接在属性上定义函数也是可能的,但这会使导出对象的结构很难看到。@vicatcu
.bind(this)
实际上是我最初拥有的,但这会阻止类型信息(特别是函数参数类型)被继承。@PatrickRoberts,很抱歉,我确实误解了你的建议。您完全正确,一种解决方案是将所有函数公开,而不将它们分流到一个对象中。导出对象背后的整个想法是,该文件具有约50个用于构建配置对象的函数(说来话长)。该对象不会给用户50个函数进行解析,而是提供有组织的选择,以获得特定用例所需的函数。TypeScript是否可以阻止用户直接调用私有方法
utilityservice.utilFunction1()
是的,typescript可以实现OOP的所有四个原则。只需在开发模式服务器日志错误中尝试
utilityservice.utilFunction1()
,在浏览器中我看到该方法被真正调用-在浏览器控制台中查看结果。感谢@ioedeveloper!它确实达到了我想要的。这比我希望的要详细一点,但是有一种方法来获取这些函数的参数类型真的很好。非常感谢,非常感谢。不幸的是,我在宣布这个解决方案成功之前并没有尽可能多地测试它。经过进一步调查,这并没有让我达到我需要的地方。这样做与将私有函数直接分配给属性没有明显区别。我还意识到我需要对我原来的问题进行澄清。我会把它编辑一下。
let _otherService: OtherService;

export class MyUtilClass {

    constructor(private otherService: OtherService) {
        _otherService = otherService;
    }

    public exposedObject = {
        prop1: utilFunction1
    };
}

function utilFunction1() {
    utilFunction2();
}
function utilFunction2() {
    _otherService.doSomething();
}