Ramtin Soltani
Ramtin Soltani

Reputation: 2710

Access members of inner class from the outer class - TypeScript

I'm trying to group some members of a class in TypeScript. Consider the following class:

export class MyClass {

  private member: string = 'foo';

  public getFoo(): string {

    this._doSomething();

    return this.member;

  }

  // Helper
  _doSomething() { console.log(this.member); }

}

What I basically want to do is to wrap _doSomething with a namespace (let's call the namespace helpers) so inside getFoo() I can call this.helpers._doSomething().

Of course, this is super easy to do in Javascript since we can define an object as a member and define the helper functions inside the object.

In TypeScript, I almost got the same effect through class expressions:

export class MyClass {

  private member: string = 'foo';

  public getFoo(): string {

    this.helpers._doSomething();

    return this.member;

  }

  private helpers = class {

    // To have access to the parent's members
    constructor(private parent: MyClass) { }

    public _doSomething() { console.log(this.parent.member); }

  };

}

The only problem is that the MyClass can't have access to helpers class members.

How do I get access to the inner class members from the outer class?

Is there a better way to achieve the namespace helpers?

Any help would be appreciated.


Updated

Using the accepted answer achieves the goal:

export class MyClass {

  private member: string = 'foo';

  public getFoo(): string {

    this.helpers._doSomething();

    return this.member;

  }

  private helpers = new (class {

    // To have access to the parent's members
    constructor(private parent: MyClass) { }

    public _doSomething() { console.log(this.parent.member); }

  })(this);

}

Upvotes: 5

Views: 1820

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250136

You just defined the class, to have access to the non-static members you have to new it up. You can do this inline like so :

export class MyClass {

  private member: string = 'foo';

  public getFoo(): string {

    this.helpers._doSomething();

    return this.member;

  }

  private helpers = new (class {

    // To have access to the parent's members
    constructor(private parent: MyClass) { }

    public _doSomething() { console.log(this.parent.member); }

  })(this);

}

Or if you want to have multiple instances of the helper class you can new it up as needed:

public getFoo(): string {

  let h = new this.helpers(this);
  let h1 = new this.helpers(this);
  h._doSomething();
  h1._doSomething();
  return this.member;

}

You can achieve a similar effect by using the merging of a class and a namespace, the problem is you will not have access to private members, while your solution requires this:

export class MyClass {
  // Must be public for access from helper
  public member: string = 'foo';

  public getFoo(): string {
    let h = new MyClass.helpers(this);
    h._doSomething();
    return this.member;
  }
}

export namespace MyClass {
  // must be exported to be accesible from the class
  export class helpers {
    // To have access to the parent's members
    constructor(private parent: MyClass) { }
    public _doSomething() { console.log(this.parent.member); }
  }
}

Upvotes: 4

Related Questions