Skip to content
Advertisement

Get the type of a nested class in TypeScript

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)

Advertisement

Answer

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.

Advertisement