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

"encountered net::ERR_NAME_NOT_RESOLVED error when trying to upload image to s3 storage

I am currently developing an application using Angular. I have been attempting to upload a picture to my S3 bucket, but each time I try, I encounter this error in the console. https://i.stack.imgur.com/qn3AD.png Below is the code snippet from my upload.s ...

The Angular Material Table is not showing any data on the screen

My challenge is to consolidate data from 4 different endpoints in order to generate a ListElement that will populate an angular material table. Despite receiving the correct data in my logs, the table remains empty. Interestingly, when I include a conditio ...

What is the correct way to implement Axios interceptor in TypeScript?

I have implemented an axios interceptor: instance.interceptors.response.use(async (response) => { return response.data; }, (err) => { return Promise.reject(err); }); This interceptor retrieves the data property from the response. The re ...

Getting a JSON value and saving it to a variable in Angular 4

Here is the JSON structure: { "Semester": [ { "queueName": "Science", "totalCount": 300, "unassignedCount": 10, "subjectDetails": [ { "subjectName": "Chemistry", "sectionOne": 100, "secti ...

What steps can be taken to dismiss a "TS2531: Object is possibly 'null'" error as a false positive if the object is always guaranteed to not be null?

Here is the code snippet: const infinoteUrl = $q.localStorage.getItem("infinote-dev-api") === null ? `${window.location.protocol}//${window.location.host}` : $q.localStorage.getItem("infinote-dev-api") console.log(`infinote UR ...

Capture the current state of a page in Next.js

As I develop my Next.js application, I've encountered an architectural challenge. I'm looking to switch between routes while maintaining the state of each page so that I can return without losing any data. While initialProps might work for simple ...

I'm encountering an issue with my Next.js development server at localhost:3001 where all routes are displaying a 404 not found page. What

Currently working on a Next.js dashboard app and encountering an issue where my localhost keeps redirecting me to the 404 page. This has happened before, but I can't recall how I resolved it. Here is the recurring problem: I attempted deleting the .n ...

Priority of Typescript TypeRoots

After extending a class from an npm package with additional type definitions, I noticed that my custom definitions are taking lower priority than the ones coming from node_modules. Is there a way to adjust the TypeScript definition priority using the typeR ...

The Next.js website displays a favicon in Chrome, but it does not appear in Brave browser

As I work on my debut next.js website, I am configuring the favicon in index.js like this: <Head> <title>Create Next App</title> <link rel="icon" href="/favicon.ico" /> </Head> Initially, all my source ...

Setting up OpenID configuration in angular-oauth2-oidc to bypass authentication for certain addresses

In my Angular project, I implemented OpenID authentication using the angular-oauth2-oidc project. However, I need to disable authentication for certain routes. To achieve this, I start the code flow in the main component and bootstrap it in the main modu ...

Looking to transform a timestamp such as "2021-07-18T9:33:58.000Z" into a more readable format like 18th July for the date or 9:33 am for the time using Angular?

Is there a way to convert the Timestamp format "2021-07-18T9:33:58.000Z" to display as 18th July (for date) or 9:33 am (for time) in an Angular 11 application? Currently, my code looks like this: const myDate = new DatePipe('en-US').transform ...

What is the correct way to declare the mongoose _id in a TypeScript interface?

I have a question about utilizing Mongoose and TypeScript using the interface+class+schema approach. When it comes to storing the _id field, what is the best method? I understand that the database stores it as a bson ObjectID. However, I've come acr ...

Checking the types of arrays does not function properly within nested objects

let example: number[] = [1, 2, 3, 'a'] // this code block correctly fails due to an incorrect value type let example2 = { demo: 1, items: <number[]> ['a', 'b'], // this code block also correctly fails because of ...

What causes the Babel JSON configuration error to appear in my project?

I'm currently working on a React website, utilizing TSX instead of JSX. In my setup, I am using webpack and Babel. However, I have encountered an error while running the webpack-dev-server. ERROR in ./src/index.tsx Module build failed (from ./node_mo ...

Methods cannot be called on TypeScript primitive strings

In my exploration of TypeScript, I came across the concept that the string primitive type does not have any methods and is simply a value. To utilize methods such as toLowerCase(), one must work with the String type instead. Curious about this distinction ...

Find with user-friendly input/label removal function (Ionic 2)

I have embarked on creating a recipe application where users can search for recipes by ingredients. I want to enhance the functionality of the search feature so that when users press the spacebar to enter the next input, it appears as a label below with an ...

tips for accessing the useState value once it has been initialized

When using the state hook in my code, I have: const [features, setFeatures] = useState([]) const [medicalProblem, setMedicalProblem] = useState([]) The medicalProblem variable will be initially populated with a response from an API call: useEf ...

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 ...

Attempting to execute a synchronous delete operation in Angular 6 upon the browser closing event, specifically the beforeunload or unload event

Is there a way to update a flag in the database using a service call (Delete method) when the user closes the browser? I have tried detecting browser close actions using the onbeforeunload and onunload events, but asynchronous calls do not consistently wor ...

Potential solution for communication issue between Angular CLI and Flask due to cross-origin error

Initially, the user id and password are submitted from the UI (angular) to Flask: public send_login(user){ console.log(user) return this.http.post(this.apiURL+'/login',JSON.stringify(user),this.httpOptions) .pip ...