What is the best way to iterate through two object keys in TypeScript?

I recently created a Vector class but I am encountering some issues with the syntax.

Here is the code snippet:

export class Vector {
  x: number;
  y: number;

  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }

  add(v: Vector) {
    var x: number, y: number;

    for (var component in this) {
      component == "x"
        ? (x = this[component] + v[component])
        : (y = this[component] + v[component]);
    }

    return new Vector(x, y);
  }
}

The issue lies in the syntax here:

https://i.sstatic.net/KPdA3.png

In the statement "return new Vector(x, y)", the error message appears as "Variable 'x' is used before being assigned". Additionally, when referencing "v[component]", the error states that "Type 'Extract<keyof this, string>' cannot be used to index type 'Vector'."

Although the code functions properly, it's important for me to rectify these syntax errors and write it correctly.

Answer №1

@T.J. Crowder made a valuable comment. If you insist on using a loop in your function, you have to specify the key type for the compiler:

TS Playground link

You can manually do it this way:

add (v: Vector): Vector {
  const vec = new Vector();

  for (const key in vec) {
    type K = 'x' | 'y';
    vec[key as K] = this[key as K] + v[key as K];
  }

  return vec;
}

Alternatively, you can use an assertion function within the remaining scope:

function assertType <T = unknown>(value: unknown): asserts value is T {}
add (v: Vector): Vector {
  const vec = new Vector();

  for (const key in vec) {
    assertType<'x' | 'y'>(key);
    vec[key] = this[key] + v[key];
  }

  return vec;
}

Answer №2

In my personal opinion, this is the method I prefer to use:

  add(v: Vector): vector {
    const res = new Vector();

    Object.keys(this).forEach(component => {
      res[component] = this[component] + v[component];
    });

    return res;
  }

I quickly put together a sandbox demonstration here

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 the nuances of checking lists in TypeScript

In the following list: empList = ['one','two','finish','one','three'] I am required to evaluate conditions based on empList: Condition 1: If 'two' appears before 'finish', set this ...

Obtaining data from a TypeScript decorator

export class UploadGreetingController { constructor( private greetingFacade: GreetingFacade, ) {} @UseInterceptors(FileInterceptor('file', { storage: diskStorage({ destination: (req: any, file, cb) => { if (process.env ...

Having trouble making API calls from the NextJS endpoint

While attempting to access an external API endpoint in NextJS, I encountered the following error message: {"level":50, Wed Jan 24 2024,"pid":4488,"hostname":"DESKTOP-S75IFN7","msg":"AxiosError: Request ...

Having trouble opening a JPEG file that was generated using the Writefile Api in Ionic-Cordova

Currently, I am using the writeFile API to create a JPEG image. The process is successful and the image is stored in the directory as expected. However, when I try to open the file manually from the directory, I encounter an error message saying "Oops! Cou ...

The enigma of TypeScript

Whenever I try to declare or initialize data members in a class, the following methods never seem to work: var view: string[]; var view: string[] = []; let view: string[]; let view: string[] = []; Even though the TypeScript documentation states that it s ...

What is the best way to bring a JavaScript library into a TypeScript project if the library includes a declaration file?

I have been attempting to utilize the type definitions from the callbag library. Unlike other libraries, callbag declares its type definition file within its package.json and is not included in DefinitelyTyped. However, when I try to import the library, I ...

What is the best way to bring in local modules within the browser environment using Playwright?

Let me illustrate what I am attempting to achieve: ../src/Foo/Bar.ts represents a local TypeScript file This particular file contains code that is designed to function within a browser environment (it utilizes WebSockets), and therefore needs to be execu ...

Raycast failing to detect objects that have been displaced from their original starting position

I am facing a challenge with using a raycast to locate objects under the mouse cursor. The issue arises when the objects are not positioned at (0, 0, 0) as they cannot be detected by the raycast. Once I move the object to any other position, it no longer r ...

Tips for ensuring a function in Angular is only executed after the final keystroke

I'm faced with the following input: <input type="text" placeholder="Search for new results" (input)="constructNewGrid($event)" (keydown.backslash)="constructNewGrid($event)"> and this function: construct ...

Troubleshooting Typescript compilation using tsc with a locally linked node package

In our project using React/React Native with Typescript, we have a mobile app built with React Native and a shared private package that is utilized by both the React Native client and the React frontend. Due to frequent changes in the shared package, we a ...

A function injected into a constructor of a class causes an undefined error

As I delve into learning about utilizing typescript for constructing API's, I have encountered a couple of challenges at the moment. Initially, I have developed a fairly straightforward PostController Class that has the ability to accept a use-case wh ...

The creation of a Firebase user account with the specified email and password

I'm currently facing an issue while creating a new user with email and password using firebase authentication. The problem arises when I try to access the displayName from the returned async call before the updateProfile function, as it returns a null ...

Issue with Jest mock function failing to trigger axios instance function causing it to return undefined

I initially found a solution on this StackOverflow thread However, I wanted to add my own helper function that generates a fresh Axios instance with the user's authentication token. Here is what I came up with: import axios from "axios"; c ...

Exploring the Way Constructors are Utilized with Decorators in TypeScript

Encountering issues when attempting to utilize constructor spreads with decorators in TypeScript, here is the code snippet: export function httpGet(path?: string, ...middlewares : Function[]) { }; Usage example: class Controller { @httpGet('/:id& ...

Tips for preventing the need to convert dates to strings when receiving an object from a web API

I am facing an issue with a class: export class TestClass { paymentDate: Date; } Whenever I retrieve an object of this class from a server API, the paymentDate field comes as a string instead of a Date object. This prevents me from calling the ...

Make TextField with type number forcibly show dot as decimal separator

I am currently utilizing the material-ui library to display a TextField component in my react application. Strangely, all instances of <TextField type="number /> are displaying decimal separators as commas (,) instead of dots (.), causing confusion f ...

Leveraging ES6 Symbols in Typescript applications

Attempting to execute the following simple line of code: let INJECTION_KEY = Symbol.for('injection') However, I consistently encounter the error: Cannot find name 'Symbol'. Since I am new to TypeScript, I am unsure if there is somet ...

Utilizing Angular and TypeScript: The best approach for managing this situation

I need some guidance on handling asynchronous calls in Angular. Currently, I am invoking two methods from a service in a controller to fetch an object called "categoryInfo." How can I ensure that these methods return the categoryInfo correctly and displa ...

Having Trouble with Ionic 2's Loading Controller

In my attempt to utilize the recently added LoadingController in this scenario: let loading=this.load.create({ content: "Connexion au serveur Migal en cours..." }); loading.present(); this.http.get(this.urlCheckerForm.value.migalUrl+'/action/Mobi ...

When using React and Material UI, there seems to be an issue with the Popover component where calling `setAnchorEl(null)` on the onClose event does not properly

I am encountering an issue with a Popover (imported from MaterialUI) nested inside a MenuItem (also imported from MaterialUI). The open prop for the popover is set to the boolean value of anchorEl. The onClose function is supposed to handle setting anchorE ...