Reputation: 638
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)
Upvotes: 2
Views: 1417
Reputation: 3672
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.
Upvotes: 1
Reputation: 4213
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.
Upvotes: 0