Exploring Typescript: Simulating Nested Classes and Accessing Private Members

Previous solutions regarding typescript and nested classes often recommended utilizing the declaration merging feature of the language. I've experimented with this approach using the code snippet below, which functions correctly but triggers a compiler error:

foo.ts(9,37): error TS2341: Property '_bar' is private and only accessible
              within class 'Foo'.

...which is puzzling because Class Bletch is indeed a part of Foo.

Is there an optimal way to address the issue of accessing a private member from the outer class? (I am aware of the workaround involving (this._foo as any) but I'm hoping for a more elegant solution.)

Example:

export class Foo {
    constructor(private _bar: number) {}
    //...
}

export module Foo {
    export class Bletch {
        constructor(private _foo: Foo) {}
        barf(): number { return this._foo._bar; }
    }
}

let a = new Foo(57);
let b = new Foo.Bletch(a)

console.log(b.barf());

Answer №1

Belonging to a class does not grant access to its private members/methods, although inner classes typically can.
In this scenario, there is no actual inner class, you are simply adding the class Bletch as a property of class Foo, which becomes clearer in the compiled JS:

var Foo = (function () {
    function Foo(_bar) {
        this._bar = _bar;
    }
    return Foo;
}());
var Foo;
(function (Foo) {
    var Bletch = (function () {
        function Bletch(_foo) {
            this._foo = _foo;
        }
        Bletch.prototype.barf = function () { return this._foo._bar; };
        return Bletch;
    }());
    Foo.Bletch = Bletch;
})(Foo || (Foo = {}));

This issue can be resolved by implementing something like this:

module Foo {
    interface Instance {
        _bar: number;
    }

    export class Bletch {
        private _foo: Instance;

        constructor( foo: Instance | Foo ) {
            this._foo = foo as Instance;
        }

        barf(): number { return this._foo._bar; }
    }
}

(code in playground)

Another approach to defining "inner classes" is available as well:

interface Instance {
    _bar: number;
}

class Foo {
    constructor( private _bar: number ) {}

    static Bletch = class {
        private _foo: Instance;

        constructor( foo: Instance | Foo ) {
            this._foo = foo as Instance;
        }

        barf(): number { return this._foo._bar; }
    }
}

(code in playground)

This alternative appears more typical and concise compared to the previous method.

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

Guide to binding dates with PrimeNG's p-calendar

<p-calendar [showIcon]="true" [(ngModel)]="model.SelectedDate" name="SelectedDate"></p-calendar> I'm currently facing an issue in my HTML code where I am unable to bind model.SelectedDate from my TypeScript file successfully. My goal is t ...

Adding text in CKEditor with Angular while preserving the existing formatting

To add my merge field text at the current selection, I use this code: editor.model.change(writer => { var position = editor.model.document.selection.getFirstPosition(); // trying to connect with the last node position.stickiness = 'toP ...

What is the best way to define a function that accepts an object with a specific key, while also allowing for any additional keys to be passed

Typescript allows us to define an interface for an object that must have a key and can also allow additional keys: interface ObjectWithTrace { trace: string; [index: string]: any } const traced: ObjectWithTrace = { trace: 'x', foo: 'bar ...

Retrieve the array from within the string

Any suggestions on how I can extract the array from this string? The current string is: "['Biller.Customer.Data@Taxonomy', 'Product.Platform and Enterprise Services Data.Data@Taxonomy']" I need to extract it to look like thi ...

I encountered an issue while making customizations to my default next.config.js file. Despite attempting various solutions, I consistently encountered an error regarding the invalid src property

I'm currently trying to introduce some custom configurations into the next.config.js file. However, I keep encountering an error regarding an invalid src prop. Despite my attempts to troubleshoot in various ways, the error persists. // ...

Angular generates a dynamic interface to fetch data from Wordpress REST API posts (special characters in property names are causing issues)

I've been developing a front-end Angular application that interacts with the Wordpress REST API to fetch and display post data. My goal is to create an interface to handle the responses and render the posts in the template. However, I encountered an ...

Loading a view in Ionic2 with Angular2 after a successful subscription

After completing an http post request, I want to navigate to the next view in my app. Here is a breakdown of the three services I am using: The server service handles generic http calls such as get and post requests. The city service stores a list of ...

Troubleshooting type inference challenges following class inheritance in TypeScript

Imagine a scenario where you have a class called Base. In this class, the print method requires a parameter that merges IBaseContext with a generic type T. interface IBaseContext { a: number } class Base<T> { public print(context: IBaseContext & ...

Encountering problems with TypeScript in a Node application when using the package manager

I am facing an issue while trying to package my node app into an exe using "pkg". I work with TypeScript, and when I attempt to run pkg index.ts --debug, an error pops up. Node.js v18.5.0 Warning Failed to make bytecode node18-x64 for file /snapshot/ ...

What is the proper way to access and modify the child component within a parent component?

I am working with nested components as shown below: app.parent.component > app.container.component > app.containeritem.component Here is an example: app.parent.component import ... @Component({ selector:'parent', template: &apos ...

Difficulty encountered when attempting to invoke a public function that makes use of a private function in TypeScript

I'm relatively new to TypeScript and I've been trying to replicate a pattern I used in JavaScript where I would expose functions through a single object within a module (like "services"). Despite my efforts, I'm facing some issues when attem ...

Issue encountered when importing a font in TypeScript due to an error in the link tag's crossorigin

How do I troubleshoot a TypeScript error when importing a custom font, such as a Google font? <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> Below is the specific error message: Type 'boolean' is ...

I am interested in updating the content on the page seamlessly using Angular 6 without the need to reload

As a newcomer to Angular, I am interested in dynamically changing the page content or displaying a new component with fresh information. My website currently features cards, which you can view by following this Cards link. I would like to update the page ...

Why can't Angular iterate through objects using ngFor in Typescript?

Here's what I currently have: public posts: QueryRef<PostsInterface>; this.posts = this._postService.get(); //in ngOnInit In my HTML file, it looks like this: <mat-card *ngFor="let post of posts | async"> This allows me to display eac ...

Troubleshooting issue: matTooltip malfunctioning in *ngFor loop after invoking Angular's change

The matTooltip in the component below is rendering correctly. The overlay and small bubble for the tooltip are rendered, but the text is missing (even though it's present in the HTML when inspecting in the browser) and it isn't positioned correct ...

Determining the return type based on an optional generic type in TypeScript

I have created a function that generates an object (map) [key] : value from an array. My goal is to make the value method optional, and if not provided, simply return the item as it is. Here is the code I have written: export default class ArrayUtil ...

What is the best way to alter the Date format in Typescript?

Within my response, the field createdate: "2019-04-19T15:47:48.000+0000" is of type Date. I am looking to display it in my grid with a different format such as createdate: "19/04/2019, 18:47:48" while maintaining its original data type. To achieve this, I ...

Using Typescript, a vuex getter that includes an argument can be implemented to

Have you ever wondered how to create a Vuex store getter that takes a parameter argument? Check out this example: https://vuex.vuejs.org/en/getters.html I'm currently working on a project using Typescript (https://github.com/hmexx/vue_typescript_star ...

Linking Redux to the highest level of my application is not functioning as expected

I have been attempting to troubleshoot this code for quite some time now, but I am struggling to identify the issue at hand. My main goal is to establish a connection between my top-level application and the redux store. However, every time I try, the stor ...

Dividing component files using TypeScript

Our team has embarked on a new project using Vue 3 for the front end. We have opted to incorporate TypeScript and are interested in implementing a file-separation approach. While researching, we came across this article in the documentation which provides ...