It's easier to understand why you can't do that if you look at the compiled javascript of your code:
var OuterClass = (function () {
function OuterClass() {
this.outerField = 1337;
this.InnerClass = (function () {
function class_1() {
}
class_1.prototype.accessOuter = function () {
return this.outerField; // outerField not defined
};
return class_1;
}());
}
return OuterClass;
}());
As you can see, outerField
is defined as a member of OuterClass
like so:
this.outerField = 1337;
When you try to access it in your InnerClass
you do:
return this.outerField;
But the this
here is the instance of class_1
and not OuterClass
so there's no outerField
in this
.
Also, you have no access from the inner class to the instance of the outer class.
The way this is solved in java is like so:
class OuterClass {
private int outerField = 1337;
public class InnerClass {
public int accessOuter() {
return OuterClass.this.outerField;
}
}
}
But there's no equivalent to OuterClass.this.outerField
in typescript/javascript.
Look at typescript inner classes more like static inner classes in java, but here too you'll only be able to access public properties:
class OuterClass {
public static outerField = 1337; // has to be public
public InnerClass = class {
public accessOuter() {
return OuterClass.outerField;
}
}
}
You can pass an instance of the outer class to the inner class:
class OuterClass {
public outerField = 1337;
public InnerClass = class {
constructor(private parent: OuterClass) {}
public accessOuter() {
return this.parent.outerField;
}
}
}
But again, you'll need to have outerField
public.
Edit
In case you want to achieve something that will simulate the needed behavior (that is, the inner class instance will have access to a private outer class members), then you can do something like this:
interface OuterClassProxy {
outerField: number;
}
interface IInnerClass {}
class OuterClass {
private outerField = 1337;
static InnerClass = class implements IInnerClass {
constructor(private parent: OuterClassProxy) {}
public accessOuter() {
return this.parent.outerField;
}
}
public createInnerClass(): IInnerClass {
let outerClassInstance = this;
return new OuterClass.InnerClass({
get outerField(): number {
return outerClassInstance.outerField;
},
set outerField(value: number) {
outerClassInstance.outerField = value;
}
});
}
}
It's quite a lot of work, but it will do it.