Retrieve a static property from a specific type

I've encountered a dilemma with the code snippet below:

class Action {
    public static DEPENDENCIES: (typeof Action)[] = [];

    public static MIN_USES: number | null = null;
    public static MAX_USES: number | null = null;
}

class SomeAction extends Action {
    public static DEPENDENCIES = [SomeOtherAction];

    public statuc MIN_USES = null;
    public static MAX_USES = 1;
}

class SomeOtherAction extends Action {
    public static DEPENDENCIES = [];

    public static MIN_USES = 1;
    public static MAX_USES = 1;
}

When trying to access a static property like this:

class Turn {
    public can(A: typeof Action) {
        console.log(A.MIN_USES);
    }
}

turn.can(SomeOtherAction); // console.log(1);

Now, I aim to give SomeOtherAction a constructor with two parameters.

This modification triggers an error message:

Class static side 'typeof SomeOtherAction' incorrectly extends base class static side 'typeof Action'.

The root of the issue lies in the differing constructor signatures, which led me to replace (typeof Action)[] with

(new(...args: any[]) => Action)[]
.

Nevertheless, by making this change, it seems that I lose the ability to access static properties:

Property 'MIN_USES' does not exist on type 'new (...args: any[]) => Action'.

Is there a way to reconcile accessing static properties and accommodating various constructor signatures?

Answer №1

Your issue stemmed from using the typeof operator, which enforces that class structures are identical, including the new property (constructor).

I resolved this problem with the following code:

type ActionType = (Omit<typeof Action, 'new'>)

class Action {
    public static DEPENDENCIES: ActionType[] = [];
    
    public static MIN_USES: number | null = null;
    public static MAX_USES: number | null = null;
}

class SomeOtherAction extends Action {
    public static DEPENDENCIES = [];

    public static MIN_USES = 1;
    public static MAX_USES = 1;

    constructor(arg1: string, arg2: number) {
        super()   
    }
}

class SomeAction extends Action {
    public static DEPENDENCIES = [SomeOtherAction];

    public static MIN_USES = null;
    public static MAX_USES = 1;
}

class Turn {
    public can(a: ActionType) {
        console.log(a.MIN_USES);
    }
}

const turn = new Turn()
turn.can(SomeOtherAction); // console.log(1);

The ActionType now represents the structure of Action without the constructor, resolving the constraint issue.

By creating and implementing this type, all occurrences of typeof Action have been replaced with ActionType.

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

Exploring Typescript: Combining types (rather than intersecting them)

Let's analyze the scenario below type MergeFn = <K1 extends string, V1, K2 extends string, V2>( k1: K1, v1: V1, k2: K2, v2: V2 ) => ??? let mergeFn: MergeFn // actual implementation doesn't matter for this question What should b ...

Encountered a type error during project compilation: "Type '(e: ChangeEvent<{ value: string[] | unknown; }>) => void' error occurred."

I recently started working with react and I'm facing an issue with a CustomMultiSelect component in my project. When I try to call events in another component, I encounter the following error during the project build: ERROR: [BUILD] Failed to compile ...

Creating a custom Higher Order Component to seamlessly connect react-relay and react-router using TypeScript

Hey there! So, my Frankenstein monster project has decided to go rogue and I'm running out of hair to pull out. Any help would be greatly appreciated. I've been working on setting up a simple app with React, React-Router, React-Relay, and Typesc ...

Button to expand or collapse all sections in Ant Design Collapse component

Is there a way to create a button that can expand or collapse all tabs in an ant.design Collapse component? I attempted to modify defaultActiveKey but it seems like this can only be done during page rendering. If possible, could someone share a code snip ...

Angular - The differ is unable to find support for the object 'Item One' which is of type 'string'. NgFor is only able to bind to Iterables like Arrays and not individual objects

Many questions on StackOverflow share similarities with this one, but I have not been able to find a solution that fits my issue. My code functions correctly when attempting to populate items in a "Select" control. It successfully retrieves data if the it ...

Issue: The module '@nx/nx-linux-x64-gnu' is not found and cannot be located

I'm encountering issues when trying to run the build of my Angular project with NX in GitHub Actions CI. The process fails and displays errors like: npm ERR! code 1 npm ERR! path /runner/_work/myapp/node_modules/nx npm ERR! command failed npm ERR! c ...

Submitting the form leads to an empty dynamically added row

I am currently working on a gender overview that allows you to edit, add, or delete genders using a simple table. The functionality of adding and deleting rows is already implemented. However, I am facing issues with displaying the correct web API data as ...

Utilize the <wbr> tag within FormattedMessage and assign it as a value while coding with TypeScript

Trying out the optional word break tag <wbr> in a message within <FormattedMessage id="some:message" />. Context Some words or texts are too lengthy for certain parent elements on smaller mobile screens, and we have a column layout t ...

The use of await can only occur inside an async function

Can someone explain the proper placement of the async keyword for me? I've tried a few different spots, but keep encountering the same error. async addNewCategory() { let alert = this.alertCtrl.create({ title: 'New Category', ...

Encountered an error when creating my own AngularJS module: Unable to instantiate

Attempting to dive into TypeScript and AngularJS, I encountered a perplexing error after following a tutorial for just a few lines. It appears that there may be an issue with my mydModule? angular.js:68 Uncaught Error: [$injector:modulerr] Failed to inst ...

Subclass method overloading in Typescript

Take a look at this example: class A { method(): void {} } class B extends A { method(a: number, b: string): void {} } An error occurs when trying to implement method() in class B. My goal is to achieve the following functionality: var b: B; b.met ...

When it comes to passing prop values through functions, TypeScript types do not provide suggestions

I'm struggling to find a way to ensure that developers have suggested types for specific props in my component, regardless of how they pass data to the prop. For example, when I directly pass an array of values to the prop: <Component someProp={[{ ...

What is the method for adjusting the spacing between binding tags within HTML code formatting specifically for TypeScript elements in IntelliJ?

My Angular binding currently defaults to <h1>{{typeScriptVar}}</h1>, but I would like it to be set as <h1>{{ typeScriptVar }}</h1> when I use the format code shortcut in InteliJ. Can anyone assist me with this issue? I have resear ...

What prevents TypeScript from automatically inferring tuple return types in RxJs streams?

When composing an observable stream, the map function infer is a union instead of a tuple. For instance: import { Component } from '@angular/core'; import { from } from 'rxjs'; import { map, tap } from 'rxjs/operators'; expo ...

"Enhance your Vue 3 projects with a dynamic library featuring universal components and full

Currently, I am in the process of developing a Vue 3 component library using Vue 3, Vite, and TypeScript. The unique aspect about this library is that it installs as a plugin and registers all components as global entities. Here is an overview of how this ...

Error message in Ionic 2: "Property is not found on type"

Currently, I am working on a project in Ionic 2 and have encountered a stumbling block with a seemingly simple task. My issue lies with a Textbox where I aim to input text that will then be displayed. I found some code on a website (http://www.tizag.com/j ...

Using capital letters with interpolated language keys

The issue: I'm currently facing a problem with i18next. It allows variable interpolation in strings, like "AddNew": "Add new {{item}}". However, I have a language where the grammar requires "{{item}}" to be the first word, as in "AddNew": "{{item}} t ...

How can I utilize a filter or pipe to populate product categories onto screens within Ionic 2?

I am considering creating an Ionic 2 app with 6 pages, but I'm unsure whether to utilize a Pipe or a Filter for the individual category pages and how to implement the necessary code. Each category page should be able to display products from the "app ...

Leveraging the 'styled()' utility from the MUI System while incorporating extra properties (Typescript)

I'm currently tackling a project using MUI System v5. I've opted to use the styled() utility (not styled-components) for styling and creating basic UI components. TypeScript is being used in this project, but I am facing a number of challenges as ...

How to send multiple queries in one request with graphql-request while using getStaticProps?

I am currently utilizing graphCMS in combination with NextJS and have successfully implemented fetching data. However, I am facing an issue where I need to execute 2 queries on the homepage of my website - one for all posts and another for recent posts. q ...