How to Access Static Method from Non-Static Method in TypeScript

Within my hierarchy, there is some static content present in all levels (for example, the _image). It would be ideal to access the corresponding _image without repeating code:

Here's what I envision:

class Actor {
    static _image; // Needs to be static

    method show(){  // Needs to be non-static
        this.setImage(this.class._image); // Doesn't work....
    }
}

class GoodActor extends Actor {
    static _image = 'good.png'
}

class BadActor extends Actor {
    static _image = 'bad.png'
}

class MediumActor extends Actor {
    static _image = 'medium.png'
}

Unfortunately, it doesn't work. At the moment, I've only managed to get to:

class Actor {
}

class GoodActor extends Actor {
    static _image = 'good.png'  // Needs to be static

    method show(){   // Needs to be non-static
        this.setImage(GoodActor._image);
    }
}

class BadActor extends Actor {
    static _image = 'bad.png'  // Needs to be static

    method show(){  // Needs to be non-static
        this.setImage(BadActor._image);
    }
}

class MediumActor extends Actor {
    static _image = 'medium.png'  // Needs to be static

    method show(){  // Needs to be non-static
        this.setImage(MediumActor._image);
    }
}

If these four classes have more methods, I don't want to repeat the show() method in each subclass... However, I require the show() method to be non-static and the _image to be accessed statically.

I have come across this issue in TypeScript: https://github.com/Microsoft/TypeScript/issues/7673, but unfortunately, I can't seek help there as they have closed it without a solution. None of them addressed the challenge of dynamically resolving the static method for invocation.

Answer №1

Update: Have you considered the rationale behind not creating individual objects before caching images? By ensuring that object construction is cost-effective, using static fields may not offer any advantages.

For instance:

class Character {
    image: string;

    displayImage() {
        console.log(this.image);
    }
}

class GoodCharacter extends Character {
    image = 'good.png';
}

class EvilCharacter extends Character {
    image = 'evil.png';
}

const characterTypes: (typeof Character)[] = [GoodCharacter, EvilCharacter];

function preloadImages() {
    for (let characterType of characterTypes) {
        preloadImage(new characterType().image);
    }
}

function preloadImage(image: string) {
    console.log(`Loading ${image}`);
}

preloadImages();

// "Loading good.png"
// "Loading evil.png"

Answer №2

Just a heads up, you have the ability to access the class of the current object using constructor, not class. Be sure to declare it with a more specific type than just Function.

class Character {
    static _avatar: string; // I want this to be a static property

    // Keep static members, but remove construct signature since subclasses can have different constructors.
    "constructor": Pick<typeof Character, keyof typeof Character>;

    display(){  // This should be an instance method
        this.setAvatar(this.constructor._avatar);
    }
}

class Hero extends Character {
    static _avatar = 'hero.png'
}

class Villain extends Character {
    static _avatar = 'villain.png'
}

class Sidekick extends Character {
    static _avatar = 'sidekick.png'
}

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

Converting an array of arguments into tuples within the range of <T extends Tuple> is denoted by [T, (...args: NonNullArray<T>) => any], where each tuple represents the argument of a

Let's start with a simple function that takes a tuple as its first argument and a function whose arguments are elements of the tuple that are not null as its second argument: let first: number | null | undefined; let last: number | null | undefined; l ...

The data table fails to display updated information from the data source

After updating the data-array (FileDto), I am unable to see any changes reflected in the Datatable. I have tested outputting the data using ngFor, and it works perfectly fine. Here is the HTML code: <ngx-datatable class="material striped" [rows]= ...

Create Office Script calculations with quotations included

I am currently attempting to create an Excel office script formula for a cell. Are there any tips on how to insert a formula with quotes into a cell? For example, the following works fine: wsWa.getCell(WaRangeRowCount, 9).setFormula("= 1 + 1"); ...

Global Enum in Typescript that is Optimized for Inlining during Compilation

I'm facing a challenge with an enum that is widely used in my project. Having to import it into every file is becoming cumbersome. Is there a way to define the enum in the .d.ts file so that it automatically gets included when compiled to Javascript? ...

Efficiently loading data in a table with a universal filter feature using Angular with PrimeNG

Recently, I managed to set up a datatable with the functionalities of both Lazy loading and global filter. Utilizing PrimeNG components for this implementation was a breeze. However, an issue surfaced where the global filter ceased to function when lazy lo ...

What is the best way to update typings.json and typing files?

Here is the structure of my typings.json: { "globalDependencies": { "aws-sdk": "registry:dt/aws-sdk#0.0.0+20160606153210" }, "dependencies": { "lodash": "registry:npm/lodash#4.0.0+20160416211519" } } Currently, I find it tedious to update ...

Is there a way to go back to the previous URL in Angular 14?

For instance, suppose I have a URL www.mywebsite.com/a/b/c and I wish to redirect it to www.mywebsite.com/a/b I attempted using route.navigate(['..']) but it seems to be outdated and does not result in any action. ...

Mapping JSON objects to TypeScript Class Objects

I am in the process of transitioning my AngularJS application to Angular 6, and I'm encountering difficulties converting a JSON object into a TypeScript object list. In my Angular 6 application, I utilize this.http.get(Url) to retrieve data from an AP ...

The type 'HTMLDivElement | null' cannot be assigned to the type 'HTMLDivElement' in this context

Struggling with a scroll function to maintain position while scrolling up or down - encountering an error: Error: Type 'HTMLDivElement | null' is not assignable to type 'HTMLDivElement'. Type 'null' is not assignable to type & ...

Converting objects to arrays in Typescript: A step-by-step guide

Can anyone assist me in converting a string to a Typescript array? Any help would be greatly appreciated. Take a look at the following code snippet: private validateEmptyOption(): any { console.log("CHECKED") let isValid = true; this.currentF ...

What are the recommended guidelines for using TypeScript effectively?

When facing difficulties, I have an array with functions, such as: this._array = [handler, func, type] How should I declare this private property? 1. Array<any> 2. any[] 3. T[] 4. Array<T> What is the difference in these declarations? ...

Sorting array of arrays in TypeScript and Node.js involves defining the arrays and then applying a sorting algorithm

Recently delved into TypeScript with limited JavaScript knowledge just a couple of weeks ago. I am attempting to scan through all the files in a particular directory, gather each file name (string) and modification time (number>), then organize them in ...

Different ways to showcase a value from the CSS file on the console using console.log

In this guide, you can learn how to create a custom directive in Angular by following this tutorial: Custom Directive Tutorial. The directive should function as intended. Still, I want to see the color value set in the CSS file displayed on the console us ...

Filtering an RXJS BehaviorSubject: A step-by-step guide

Looking to apply filtering on data using a BehaviorSubject but encountering some issues: public accounts: BehaviorSubject<any> = new BehaviorSubject(this.list); this.accounts.pipe(filter((poiData: any) => { console.log(poiData) } ...

How can I configure Angular to redirect to an error page whenever an error is encountered in an HTTP API request?

With over 50 HTTP APIs in my application, I'm looking for a way to automatically route to a specific page whenever an error message or issue arises with one of the APIs. Instead of manually adding routing to each service, I want to find a simpler and ...

A peculiar quirk with Nuxt.js radio buttons: they appear clickable but are somehow not disabled

I’m having an issue with a radio button that won’t check. It seems to be working fine on other pages, but for some reason it just won't click here. <div class="form-group"> <label class="control-label&q ...

Issue with ion-select default value not being applied

In my ion-select element, I have multiple options and I want to set a default value based on the CurrentNumber when the view is loaded. Here's the code snippet: <ion-select formControlName="Level"> <ion-option [value]="level.id" *n ...

When incorporating Papaparse with Angular 2, encountering the issue "Identifier 'Papa' is not found" may arise

Currently, I am facing an issue in my project where after deleting and re-installing node_modules to resolve errors, the definition of 'Papa' is missing. As a result, when npm updated the node modules again, Angular 2 is unable to find 'Papa ...

Warning: React has detected that a non-boolean value of `true` was received for the attribute `my-optional-property`

source code import React from "react"; import { Button, ButtonProps } from "@material-ui/core"; interface MyButtonProps extends ButtonProps { "aria-label": string; "my-optional-property"?: boolean; } function MyCustomButton(props: MyButtonProps) { ...

Typescript error message TS2314: One type argument is required for the generic type 'Array<T>'

I recently started my journey in learning typescript and have written some basic code. class Learning { subjects: Array[string]; hoursPerDay: number; constructor(subj: Array[string], hrs: number) { this.subjects = subj; thi ...