I'm using nested classes in TypeScript by using the following code:
class Parent {
private secret = 'this is secret'
static Child = class {
public readSecret(parent: Parent) {
return parent.secret
}
}
}
This is based on the following answer. It allows my Child class to access private properties of the Parent class.
I want to type a variable with the nested class type, I started naïvely with the following code:
type NestedType = Parent.Child
const child: NestedType = new Parent.Child()
But I get the following error:
'Parent' only refers to a type, but is being used as a namespace here. ts(2702)
I tried to use the typeof operator:
type NestedType = typeof Parent.Child
const child: NestedType = new Parent.Child()
But it doesn't work:
Property 'prototype' is missing in type '(Anonymous class)' but required in type 'typeof (Anonymous class)'. ts(2741)
Finally I was able to make it work:
const nestedTemplate = new Parent.Child()
type NestedType = typeof nestedTemplate
const child: NestedType = new Parent.Child()
However, this code creates a useless instance of Child. Is this a limitation of the TS language?
FYI, I also tried by using namespaces:
class Parent {
private secret = 'this is secret'
}
namespace Parent {
export class Child {
public readSecret(parent: Parent) {
return parent.secret
}
}
}
But then the Child class is no longer able to access the private properties of the Parent class:
Property 'secret' is private and only accessible within class 'Parent'. ts(2341)
Using the typeof child prototype should be enough to resolve your typings trouble.
class Parent {
private secret = 'this is secret'
static Child = class {
public readSecret(parent: Parent) {
return parent.secret
}
}
}
const child: typeof Parent.Child.prototype = new Parent.Child();
console.log(child.readSecret(new Parent()));
You can test it there Playground Link
That way you do not have to instantiate any intermediary classes.
You can access the Child class via the interface property access notation (foo["bar"]):
class Parent {
private secret = 'this is secret'
static Child = class {
public readSecret(parent: Parent) {
return parent.secret
}
}
}
type ParentChildProto = (typeof Parent)["Child"];
const child: InstanceType<ParentChildProto> = null!; // same as assigning to `new Parent.Child()`
child.readSecret(new Parent());
Edit: Use built-in InstanceType see comment.