Determine characteristics of object given to class constructor (typescript)

My current scenario involves the following code:

abstract class A {
    obj;

    constructor(obj:{[index:string]:number}) {
        this.obj = obj;
    }
}

class B extends A {
    constructor() {
        super({i:0})
    }

    method() {
        //I want intellisense to only suggest this.obj.i here
    }
}
class C extends A {
    constructor() {
        super({i:0,j:0})
    }

    method() {
        //I want intellisense to only suggest this.obj.i and this.obj.j here
    }
}

In class B, I am looking for autocomplete options related to the object passed in the constructor, and the same goes for class C. Is there a way to achieve this, or is there a mistake in my approach?

Answer №1

If you're looking to utilize a generic class similar to the example provided, consider using the following approach:

abstract class A<T extends Record<string, number> = Record<string, number>> {
    obj: T;

    constructor(obj:T) {
        this.obj = obj;
    }
}

class B extends A<{ i: number }> {
    constructor() {
        super({i:0})
    }

    method() {
        //In this scenario, I'm seeking intellisense suggestions limited to this.obj.i
    }
}
class C extends A<{ i: number, j: number }> {
    constructor() {
        super({i:0,j:0})
    }

    method() {
        //Here, I wish for intellisense to only propose this.obj.i and this.obj.j
    }
}

Experiment with it in this live play area

Answer №2

Interactive

Revamped for a more thorough approach. The detailed explanations embedded in the code offer a clearer understanding, emphasizing the use of generics defined in class A and properties like public readonly i: _type_def_ to target specific key-value pairs. In Class C, you can now access this.i or this.j. You can also leverage the methods of the Object constructor to deconstruct and reconstruct super.obj vs this.obj properties, with constant checks for object equality.

To directly access this.obj.i, without using Object constructor methods beforehand for deconstruction, additional advanced TS generics would need to be implemented. It is feasible to work with this.obj through different approaches, one being:

// Accessing "i" key and its corresponding value

const iValue = Object.values(this.obj)[0].valueOf();
const iKey = Object.keys(this.obj)[0].toString();

// Reconstructing to achieve this.obj.i

const thisObjI = { [iKey]: iValue }
abstract class A<
  T extends number extends { [index: string]: infer U } ? U : number
> {
  obj;

  constructor(obj: Record<string, T>) {
    this.obj = obj;
  }
  // Inferred:
  // constructor A<T extends number>(obj: Record<string, T>): A<T>
}

class B extends A<0> {
  constructor(public readonly i: number extends infer U ? U : number) {
    super({ i: 0 });
    // Inferred:
    // constructor A<0>(obj: Record<string, 0>): A<0>
  }

  stringify() {
    return JSON.stringify(
      {
        i: this.i as number, 
        sup: super.obj as Record<string, 0> 
      },
      null,
      2
    );
  }

  objValueOfCompare(valOne: number, valTwo: number) {
    return valOne === valTwo ? true : false;
  }

  truthyCheck() {
    const extractValueFromSuper = Object.values(super.obj)[0].valueOf();
    const iIsValueOfObjRecord = <
      T extends typeof this.i extends Record<string, infer U>
        ? U
        : typeof this.i
    >(
      objectCompare: T
    ) => {
      const extractThisInjectedObjectValue =
        Object.values(objectCompare)[0].valueOf();
      return this.objValueOfCompare(
        extractValueFromSuper,
        extractThisInjectedObjectValue
      );
    };
    return iIsValueOfObjRecord; // Returns True
  }
}
...

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

Tips for selecting an image from the gallery with IONIC 3

Looking for guidance on extracting an image from the gallery in IONIC 3? I attempted to grab an image from the gallery but encountered some issues. Visit this link for more information This resource may also be helpful ...

Encountering a tuple type TypeScript error with a spread argument is far too frequent an occurrence

Encountering this error is becoming a frequent occurrence for me, and I am currently unable to resolve it. src/graphics.ts:105:55 - error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter. 105 _queue.forEach((_ ...

Cross-origin request error persists despite configuring headers on the server. Unable to successfully relocate image to designated directory on the server

I am encountering a CORS error specifically when sending delete requests from Angular to Laravel. Additionally, I am facing issues with moving car model images to the directory during posting, resulting in errors. I have implemented a CORS middleware and a ...

Bringing Typescript functions into the current module's scope

Is it possible to import and reference a module (a collection of functions) in typescript without the need for the Module. prefix? For instance: import * as Operations from './Operations'; Can I access Operations.example() simply as example()? ...

Transform JSON into a TypeScript interface with a specialized Date method

Within my Angular 7 project, there is a Post Model defined as follows: export interface PostModel { id: number; created: Date; published: boolean; title: string; } I have implemented an Angular service method aimed at retrieving posts: public g ...

What is the process of extending a class in TypeScript?

I have a few services that contain the same code: constructor (private http: Http) { //use XHR object let _build = (<any> http)._backend._browserXHR.build; (<any> http)._backend._browserXHR.build = () => { let _xhr = _ ...

Is there a way to dynamically create a property and assign a value to it on the fly?

When retrieving data from my API, I receive two arrays - one comprising column names and the other containing corresponding data. In order to utilize ag-grid effectively, it is necessary to map these columns to properties of a class. For instance, if ther ...

Passing a class as a parameter in Typescript functions

When working with Angular 2 testing utilities, I usually follow this process: fixture = TestBed.createComponent(EditableValueComponent); The EditableValueComponent is just a standard component class that I use. I am curious about the inner workings: st ...

What is the quickest method for setting up types for node packages?

Whenever I need to use typed packages in my Node.js projects, there are two steps I have to take: Firstly, install the original package. For example: npm install express -S Secondly, install its type definition package. npm install @types/express -D I f ...

Sharing the label element as a prop in React component

I encountered the following code snippet: <div className="input-field"> <label htmlFor="timeObjective">Time Objective</label> <FrequencySet label='label'/> //HERE </div> My goal is to tra ...

Loading dynamic components asynchronously in Vue 3 allows for improved performance and enhanced user experience

My goal is to dynamically display components based on their type. Here's how I'm approaching it: I have several similar components that should show different content depending on their type. Using the defineAsyncComponent method, I can easily im ...

Create a functioning implementation for retrieving a list of objects from a REST API

I am looking to incorporate an Angular example that retrieves a list from a REST API. Here is what I have attempted: SQL query: @Override public Iterable<Merchants> findAll() { String hql = "select e from " + Merchants.class.getName ...

What is the best way to showcase a component using FlatList?

Discovering the power of React Native combined with TypeScript and Redux Toolkit Hello! I'm currently facing an issue with rendering a list of messages using FlatList. Everything renders perfectly fine with ScrollView, but now I need to implement inf ...

The image is malfunctioning in the production environment, but functions perfectly on the localhost server

Currently, I am in the process of creating a website utilizing Next.js and Mantine. In order to incorporate my logo into the Header section, I utilized the Image component from next/image. Unfortunately, upon deployment, the image does not display as inten ...

Access information from a different component within the route hierarchy

Suppose you have three components named A, B, and C with the following routing direction: A -> B -> C To retrieve data from the previous component (going from C to get data from B), you can use the following lines of code: In Component C: private ...

Finding it challenging to adapt an AngularJs component-based modal to TypeScript

When creating an AngularJS component in JavaScript and displaying it as a modal using ui-bootstrap, you need to pass bindings that the modal instance can use for dismissing or closing itself: app.component("fringeEdit", { controller: "FringeEditCont ...

The service that offers an Observable on a specific subject is not receiving any notifications

The EventSpinner component is designed to subscribe to icons provided by the EventsService. @Component({ selector: 'event-spinner', template: ` <div class="col-xs-5"> Test <i class="fa fa-2x" [ngClass]="{'fa-check' ...

Issue encountered with Firebase JS SDK: firebase.d.ts file is missing which leads to a Typescript error when trying to

I'm currently working on an Ionic project with AngularFire. I encountered a typescript error when trying to run ionic cordova build --prod --release android. typescript error '/home/sebinbenjamin/workspace/myapp/node_modules/firebase/firebase. ...

Guide to organizing documents using an interface structure

I currently have an interface that outlines the structure of my documents within a specific collection: interface IGameDoc { playerTurn: string; gameState: { rowOne: [string, string, string] rowTwo: [string, string, string] ...

The route information is not appearing on the screen

I am facing an issue with my application's route called home. The content on this route is not being displayed; instead, only the menu from app.component is shown. I believe I might be overlooking something obvious. Can someone assist me with this pro ...