[英]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: number
、 pointsAgainst: number
和updateStats: 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.