I'm playing with nested classes in Typescript/Javascript to model what is possible in Java. This works pretty well. I can have static and non-static nested classes, derive from each other and so on. This is my test declaration:
class OuterClass {
public static InnerClass2 = class InnerClass2 {
public static InnerClass3 = class InnerClass3 {
};
public update(o: OuterClass): void {
o.a = "b";
}
};
public InnerClass1 = (($outer) => {
class InnerClass1 {
public static InnerClass3 = class InnerClass3 {
};
public update(): void {
$outer.a = "b";
}
}
return InnerClass1;
})(this);
public InnerClassDerived = (($outer) => {
class InnerClass extends this.InnerClass1 {
public constructor() {
super();
this.update();
}
}
return InnerClass;
})(this);
private a = "a";
private list: Array<InstanceType<typeof this.InnerClass1>> = [];
public test(): void {
const i = new this.InnerClass1();
this.list.push(i);
i.update();
}
}
What bothers me, however, is this line:
private list: Array<InstanceType<typeof this.InnerClass1>> = [];
because of the long type description for the array. If InnerClass1
were static I could define a type for it in a separate namespace, like for InnerClass2
:
export namespace OuterClass {
export type InnerClass2 = InstanceType<typeof OuterClass.InnerClass2>;
}
But that's not possible, as I need that this
qualifier. Local type definitions in classes are not possible from what I know, so how could a possible solution look like to avoid the lengthy type in the array type declaration?
Ideally I would like to have this:
private list: this.InnerClass1[] = [];
CodePudding user response:
You were quite close to the solution. Instead of returning the class definition in the factory class properties, you should instead return a class expression. Then, you can access the type of InnerClass1
via OuterClass["InnerClass1"]
class OuterClass {
public static InnerClass2 = class InnerClass2 {
public static InnerClass3 = class InnerClass3 {
};
public update(o: OuterClass): void {
o.a = "b";
}
};
public InnerClass1 = (($outer) => {
return class InnerClass1 {
public static InnerClass3 = class InnerClass3 {
};
public update(): void {
$outer.a = "b";
}
};
})(this);
public InnerClassDerived = (($outer) => {
return class InnerClass extends this.InnerClass1 {
public constructor() {
super();
this.update();
}
}
})(this);
private a = "a";
private list: Array<OuterClass.classes.InnerClass1> = [];
public test(): void {
const i = new this.InnerClass1();
this.list.push(i);
i.update();
}
}
export declare namespace OuterClass {
export namespace classes {
export type InnerClass1 = InstanceType<OuterClass["InnerClass1"]>;
export type InnerClass2 = InstanceType<typeof OuterClass["InnerClass2"]>;
}
}