Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

288
Views
Update dynamic key in class in Typescript

I have a class, for example:

class Team {
  pointsFor: number;
  pointsAgainst: number;
  
  constructor(){
    this.pointsFor = 0;
    this.pointsAgainst = 0;
  }
}

Now I would like to make a method for this class where I can update the property by key for example:

updateStats = (bool: boolean, property: string, increment: number) =>{
  const key: keyof this = bool ? `${property}For` : `${property}Against`
  this[key] += increment
}

However I get an error that string is not assignable to keyof this, and if I force the type like

const key: keyof this = bool ? `${property}For` as keyof this : `${property}Against` as keyof this

then I get an error: "Operator '+=' cannot be applied to types 'this[keyof this]' and 'number'."

Is there a way to accomplish what I want here where I call team.updateStats(true, 'points', 2) and update pointsFor?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

I really wouldn't recommend using string manipulation with TypeScript class properties the way you are trying to.

By using keyof this, you are essentially referring to all the keys of the class, like pointsFor: number, pointsAgainst: number, and updateStats: Function. As you can see, not all of them are numbers.

Another issue is that a string can be anything, so updateStats(true, 'blah blah', 3) could become valid if TypeScript didn't stop you.

It would be much better to constrain the specific properties you need to an object within the class with clearly defined properties.

For example:

class Team {
  teamProps: { [key: string]: { for: number, against: number }} = {
    points: { for: 0, against: 0 }
  }

  updateStats = (bool: boolean, property: keyof typeof this.teamProps, increment: number) =>{
    this.teamProps[property][bool ? 'for' : 'against'] += increment;
  }
}

You can access these properties with <Team>.teamProps.points.for instead of <Team>.pointsFor.

about 4 years ago · Juan Pablo Isaza Report

0

You can do nearly everything with TypeScripts typesystem:

TeamProp takes a union of keys (keyof this in this case) and returns only strings, that match ${string}For or ${string}Against.

type TeamProp<K> = K extends `${infer P}For` ? P : K extends `${infer P}Against` ? P : never;

class Team {
    pointsFor: number;
    pointsAgainst: number;

    constructor() {
        this.pointsFor = 0;
        this.pointsAgainst = 0;
    }

    updateStats<P extends TeamProp<keyof this>>(bool: boolean, property: P, increment: number) {
        const key = bool ? `${property}For` : `${property}Against`
        this[key] += increment
    }
}

const t = new Team()

// Works
t.updateStats(true, 'points', 1);

// Argument of type '"foo"' is not assignable to parameter of type '"points"'.
t.updateStats(true, 'foo', 1);
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!