Expanding a Singleton Class in TypeScript

Looking to customize and expand a method within a Singleton Class using TypeScript? Here is the code for the Singleton Class:

class Singleton {
    protected static _instance: Singleton;

    protected constructor() { }

    public static get instance() {
        if (Singleton._instance === undefined) {
            Singleton._instance = new Singleton();
        }

        return Singleton._instance;
    }

    public doWork() {
        console.log('doing work in singleton...');
    }
}

ExtendedSingleton Class:

class ExtendedSingleton extends Singleton {
    protected static _instance: ExtendedSingleton;

    protected constructor() {
        super();
    }

    public static get instance() {
        console.log('Creating Extended Singleton');
        if (ExtendedSingleton._instance === undefined) {
            ExtendedSingleton._instance = new ExtendedSingleton();
        }

        return ExtendedSingleton._instance;
    }

    public doWork() {
        console.log('doing work in extended singleton...');
    }
}

Finally, here is the code that executes both classes:

Singleton.instance.doWork();
ExtendedSingleton.instance.doWork();

The issue arises when both logs display 'do work in singleton...'. When swapping the lines, the problem seems to be resolved. The cause of this behavior may be related to how JavaScript's inheritance functions. Are there any alternative solutions or best practices you recommend?

Note: I was able to resolve the issue by utilizing an interface and implementing it in both classes. However, this might not be the most efficient approach for larger classes that require overriding specific methods.

Answer №1

When ExtendedSingleton inherits from Singleton, static properties accessed on ExtendedSingleton will first be checked in the parent class, Singleton.

If _instance is defined in Singleton before being set in ExtendedSingleton, accessing ExtendedSingleton._instance will return the value set in Singleton. This behavior also works in reverse; if ExtendedSingleton does not have an _instance field, it will create its own before inheriting one from Singleton.

In cases where _instance is declared as protected but should really be private (since each class should have its own instance), TypeScript will flag this as an error.

To resolve this issue, renaming the _instance variable in either or both classes can ensure that each class maintains its own unique instance field.

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

Firebase console does not show any console.log output for TypeScript cloud functions

I encountered an issue while using Typescript to write some Firebase cloud functions. Here is a snippet of my code: index.ts export * from "./Module1"; Module1.ts import * as functions from "firebase-functions"; export const test = functions.https.onR ...

Top method for transferring information from a service to a dynamic format in Angular5

Looking for the most efficient method to populate a form with data from a service in Angular 5. My goal is to keep component code to a minimum and have the variable-data stored within services rather than components. The content is loaded through a second ...

Using NPM in combination with React and TypeScript to incorporate AMD modules

I am currently in the process of setting up a development environment for an application that is written in TypeScript using React. I already have existing TypeScript code that compiles to ES5 and AMD modules. My goal is to avoid any JavaScript transpilat ...

Preserving the state of an Angular application across page refreshes

What is the best way to maintain state persistence between page reloads? I'm not referring to state management with ngrx, but rather the scenario where refreshing the page causes user logouts, unsaved changes, and other data loss. Initially, I consid ...

The debugger extension for Visual Studio Code in Chrome, [webkit-debug-adapter], received a response from the target application, but was unable to find any valid target

I am currently working on an Angular/TypeScript application and have been able to debug the TypeScript code in Chrome thanks to the map files. Recently, I decided to install the Debugger for Chrome extension from Visual Studio Marketplace. You can find it ...

What is the process for exporting services within a module?

Is there a way to export a service from a module in angular 2? I am looking to import the service into another component without specifying the exact location of the service. I believe it should be the responsibility of the module to handle this. Core.mo ...

Hold off on addressing the nested loops within a TypeScript subscription

Goal: Ensure all nested loops complete processing before returning final value. Problem: Final value returned prematurely, before completion of loop processing. In the code snippet below, I am sending paramListToComplete to a data service for creating a ...

Having difficulty installing TypeScript on my machine

https://i.stack.imgur.com/l6COf.pngHaving trouble installing TypeScript with the following error: npm WARN registry Using outdated package data from https://registry.npmjs.org/ due to an error during revalidation. npm ERR! code E500 npm ERR! 500 Interna ...

What is the method for activating a hook after a state change in a functional component?

I'm currently working on a custom pagination hook that interacts with an API to fetch data similar to React Query. The concept is straightforward. I aim to invoke this hook whenever a specific state (referred to as cursor) undergoes a change. Below i ...

How to access a static TypeScript variable in Node.js across different files

I encountered a situation like this while working on a node.js project: code-example.ts export class CodeExample { private static example: string = 'hello'; public static initialize() { CodeExample.example = 'modified'; } ...

Troubleshooting TypeScript issues in an Angular 4 tutorial demo

I recently started working on the Angular tutorial provided on the official website. However, I have encountered an issue that I am struggling to resolve. After using Angular CLI to create the project, I came across the following code in app.component.ts: ...

PostgreSQL reverse relationship

I have a table in my database called "textDate" class TextData extends BaseEntity{ id(primaryGeneratedColumn) ar:string en:string } This entity is used to store all text in my project, such as titles, descriptions, and other fields that have foreign ...

Creating a Typescript version of the mongodb project aggregation functionality

Present scenario: I am currently working on creating a type-safe wrapper for the node-mongodb driver. I am facing challenges in determining the return type for the project aggregation stage. Feel free to check out the TypeScript Playground here class Base ...

Leveraging Renderer in Angular 4

Understanding the importance of using a renderer instead of directly manipulating the DOM in Angular2 projects, I have gone through multiple uninstallations, cache clearings, and re-installations of Node, Typescript, and Angular-CLI. Despite these efforts, ...

Obtain the default/initial argument type of typescript for extension purposes

Currently, I am in the process of developing code that automatically generates type hints based on function calls related to GraphQL Nexus tasks. In one of its functions, it requires an anonymous type constructed from the attributes generated automaticall ...

Leverage Webpack to bundle ES Modules with TypeScript module aliases

Hello there, I recently created an npm module using Typescript and ES-modules. Inside the /source folder, you can find my tsconfig.json file which includes a path alias. { "compilerOptions": { "moduleResolution": "Node ...

Requiring Subclasses to Maintain Immutability

I have created a base class that contains various properties: class Component { readonly id: number readonly type: number } Now, I am looking to create some subclasses, such as: class HealthComponent extends Component { max_health: number, ...

Typescript issues arise when a library lacks any available types for download

I attempted to incorporate the react-keydown library into my project, but encountered the following error: Could not find a declaration file for module 'react-keydown'. '/home/path../node_modules/react-keydown/dist/index.js' implicitl ...

What is the reason for this assignment not being activated?

After going through the official xstate tutorial, I decided to create my own state machine inspired by a post on dev.to by a member of the xstate team. Everything is working fine except for the fact that the output is not being updated. It seems like the ...

Tips for creating animations using parent and child components in Angular

Despite my best efforts, it seems like this should be functioning properly... but unfortunately it's not... I'm attempting to achieve a transition effect on the parent element (ui-switch-groove) while the child element (ui-switch-dongle) moves. ...