簡體   English   中英

更新 Typescript 中 class 中的動態密鑰

[英]Update dynamic key in class in Typescript

我有一個 class,例如:

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

現在我想為這個 class 創建一個方法,我可以通過鍵更新屬性,例如:

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

但是,我收到一個錯誤,即字符串不能分配給 keyof,如果我強制使用類似的類型

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

然后我得到一個錯誤:“運算符'+ ='不能應用於類型'this [keyof this]'和'number'。”

有沒有辦法在我調用team.updateStats(true, 'points', 2)和 update pointsFor的地方完成我想要的?

我真的不建議您按照您嘗試的方式對 TypeScript class 屬性使用字符串操作。

通過使用keyof this ,您實際上是指 class 的所有鍵,例如pointsFor: numberpointsAgainst: numberupdateStats: Function 如您所見,並非所有這些都是數字。

另一個問題是string可以是任何東西,因此如果 TypeScript 沒有阻止您,則updateStats(true, 'blah blah', 3)可能會變得有效。

最好將您需要的特定屬性限制在 class 中的 object 中,並具有明確定義的屬性。

例如:

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;
  }
}

您可以使用<Team>.teamProps.points.for而不是<Team>.pointsFor訪問這些屬性。

你可以用 TypeScripts 類型系統做幾乎所有事情:

TeamProp采用鍵的聯合(在本例中為keyof this )並僅返回匹配${string}For${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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM