Determine the type of a nested class within TypeScript

Utilizing nested classes in TypeScript is achieved through the following code snippet:

class Parent {
  private secret = 'this is secret'
  
  static Child = class {
    public readSecret(parent: Parent) {
      return parent.secret
    }
  }
}

This approach is inspired by this answer. It enables the Child class to access private properties of the Parent class.

To define a variable with the nested class type, one might first attempt the following:

type NestedType = Parent.Child
const child: NestedType = new Parent.Child()

However, an error is encountered:

'Parent' only refers to a type, but is being used as a namespace here. ts(2702)

An alternative using the typeof operator also proves unsuccessful:

type NestedType = typeof Parent.Child
const child: NestedType = new Parent.Child()

Ultimately, success is found in this revised approach:

const nestedTemplate = new Parent.Child()
type NestedType = typeof nestedTemplate
const child: NestedType = new Parent.Child()

Despite resolving the issue, this method does create an unnecessary instance of Child. Is this a limitation of the TS language?

Additionally, exploration was done with namespaces:

class Parent {
  private secret = 'this is secret'
}

namespace Parent {
  export class Child {
    public readSecret(parent: Parent) {
      return parent.secret
    }
  }
}

Unfortunately, utilizing namespaces results in the Child class losing access to the private properties of the Parent class:

Property 'secret' is private and only accessible within class 'Parent'. ts(2341)

Answer №1

To address your typing issues, consider utilizing the typeof child prototype.

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 experiment with it here: Playground Link

This approach eliminates the need for instantiating any intermediary classes.

Answer №2

Utilize the interface property access notation (foo["bar"]) to interact with the Child class:

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());

View in TypeScript Playground

Edit: Refer to built-in InstanceType for implementation details.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What sets apart posting data through an HTML form submission from posting data through an Ajax request?

Recently, I've encountered an issue with my Post API. When calling it through AJAX, the user parameter is received but the StreamReader returns empty. [HttpPost] [Route("getUserBankList")] public IHttpActionResult getUserBankList(UserProfile ...

Ways to integrate a security protocol with a graphql resolver

I'm currently diving into the world of graphql and I'm facing a challenge with incorporating an authentication/authorization system into my project. I stumbled upon an example on Medium, but I'm struggling to grasp how a guard connects with ...

Troubleshooting a Laravel 5.2 modal popup issue for password recovery, experiencing a 500 internal server error with the Ajax function execution

Is there a way to check if an email exists in order to send a reset password link using an AJAX function? I keep encountering a 500 internal server error before the AJAX runs. I understand that a 500 error is usually due to a token mismatch, but do I actua ...

Combining Turn.js with AJAX for an interactive web experience

I've been experimenting with turn.js and struggling to find an example of loading dynamic pages with content via ajax. While the page is loading, it's not displaying all the results. For a JSON result from the controller, click here. <div clas ...

Scope challenges with making multiple rest calls in Angular.js

As a beginner in Angular.js, I am facing an issue with $scope not receiving additional value from one of two $resource rest calls. Below is the code snippet: controller: function ($scope, $modalInstance, $route) { $scope.server = {} ...

Component in Next.js fetching data from an external API

I am attempting to generate cards dynamically with content fetched from an API. Unfortunately, I have been unsuccessful in finding a method that works during website rendering. My goal is to pass the "packages" as properties to the component within the div ...

Using AngularJS and D3 to create a custom directive that allows for multiple instances of D3 loading within Angular applications

After creating an angular directive for a d3 forced-directed graph and using the code provided here, I encountered some issues with multiple loads. The directive seemed to load six times each time it was initialized, causing performance problems. To addres ...

Challenges with line height in IE when adjusting font size in textarea

I'm facing an issue with adjusting the font size in a textarea using JavaScript. While it works perfectly in Firefox, there are some problems in IE. Specifically, the line-height does not change accordingly. This results in gaps between lines when the ...

What steps can be taken to ensure the visibility and accessibility of two vertically stacked/overlapped Html input elements in HTML?

I have encountered a challenge with my HTML input elements. There are two input elements that overlap each other, and I would like to make both inputs visible while only allowing the top input to be editable. I have tried several approaches involving z-ind ...

I keep getting redirected to a blank page by JS

I've created a JavaScript script that smoothly fades in the page when a user enters it and fades out when they click a link to another page. The script is working as intended, but I'm facing an issue with anchor links on the page. Whenever I clic ...

Is there a way to streamline this query code that seems overly complex?

Could someone please assist me in simplifying this code? I am trying to shorten or simplify the query code by using a stored procedure, but I still need to include the details inside the "()" parentheses. I am new to Node.js and would appreciate any help. ...

Steps for appending a string to a variable

Currently working on creating a price configurator for a new lighting system within homes using Angular 7. Instead of using TypeScript and sass, I'm coding it in plain JavaScript. Page 1: The user will choose between a new building or an existing one ...

Attempting to choose everything with the exception of a singular element using the not() function in Jquery

Within the mosaic (div #mosaique) are various div elements. My goal is to make it so that when I click on a specific div, like #langages or #libraries, the other divs become opaque while the selected div undergoes a size change (which works correctly in t ...

Giving identification to a pair of elements located within the same column

Struggling with assigning IDs to two elements in a single column - a dropdown and a text element. Managed it in the first scenario, but encountering issues in the second one. Seeking assistance on this matter. Scenario 1: <td> <sele ...

ReactTS: Tips for organizing child components within a "container component"

Currently, I am in the process of developing reusable front-end components in React using Typescript. However, I am encountering a challenge related to a feature commonly found in traditional packages. My goal is to have the ability to nest children of a ...

Eliminate spaces within a string using JavaScript

In my quest for knowledge about trimming strings in JavaScript, I came across this intriguing discussion with a regex-based solution. After learning from the thread, I was under the assumption that trim would eliminate the space between "Hello" and "World ...

An issue arose during the installation of nodemon and jest, about errors with versions and a pes

Currently, I am facing an issue while trying to set up jest and nodemon for my nodejs project. My development environment includes vscode, npm version 6.13.7, and node version 13.8.0. Whenever I try to install nodemon via the command line, the console disp ...

The shopping cart in our e-commerce website is refreshed in real-time thanks to the integration of J

I am currently enhancing the Codeigniter Cart with JQuery by making an Ajax call for updates. Below is my JQuery function: $(function() { $('.cart_form select').on('change', function(ev) { var rowid = $(this).attr('c ...

What is the best way to check for a matching array value in my menu list and apply a corresponding class tag to it?

I need a way to dynamically add a class to tags that match specific array values. My menu list consists of 150 items, and I want to add a class to the tag whose text matches an element in the array. <ul class="nav main" id="tabs"&g ...

AngularJS - Import and save CSV files

I have set up a nodeJS program as the server and an AngularJS web application as the client. For generating CSV files, I am utilizing the "express-csv" library (https://www.npmjs.com/package/express-csv) Below is the code for the server side: Definition ...