You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据方法参数动态选择TypeScript类属性

TypeScript动态给类属性赋值的解决方案

问题描述

现有一个Person类,通过addParameterValue方法的if判断给属性赋值,现在想改成动态赋值以去掉冗余的if逻辑,要求能给color属性正常赋值:

原类代码:

class Person { 
  name: string;
  address: string;
  color: string;
    
  addParameterValue(parameterName: string, value: string){
    if (parameterName == 'name'){
      this.name = value;
    }
    if (parameterName == 'address'){
      this.address = value;
    }
  }
}

期望执行以下代码能输出blue:

const person = new Person()
person.addParameterValue('color', 'blue')
console.log(person.color) //'blue'

踩坑记录

  1. 直接用索引赋值时,触发错误:
this[parameterName] = value;

No index signature with a parameter of type 'string' was found on type 'Person'.

  1. 用keyof Person约束参数后,又出现错误:
addParameterValue(parameterName: keyof Person, value: string){
        this[parameterName] = value
}

Type 'string' is not assignable to type '(parameterName: keyof Person, value: string) => void'.

解决方法

第二个错误的核心是keyof Person会包含类的方法名addParameterValue,如果传入这个方法名,会把方法覆盖成字符串,导致类型不兼容。因此需要把参数约束为仅类的属性名,排除方法。

方法一:用工具类型提取属性键

定义工具类型过滤掉类中的方法,只保留属性键,适合属性较多的类:

// 工具类型:提取对象中所有非方法的属性键
type OnlyPropertyKeys<T> = {
  [K in keyof T]: T[K] extends Function ? never : K
}[keyof T];

class Person { 
  // 给属性初始化默认值,避免undefined
  name: string = '';
  address: string = '';
  color: string = '';
    
  addParameterValue(parameterName: OnlyPropertyKeys<Person>, value: string){
    this[parameterName] = value;
  }
}

方法二:直接指定属性联合类型

如果类的属性不多,直接写死允许的属性名更简洁:

class Person { 
  name: string = '';
  address: string = '';
  color: string = '';
    
  addParameterValue(parameterName: 'name' | 'address' | 'color', value: string){
    this[parameterName] = value;
  }
}

测试验证

两种方法都能满足需求,执行测试代码可得到预期结果:

const person = new Person()
person.addParameterValue('color', 'blue')
console.log(person.color) // 输出 'blue'

内容的提问来源于stack exchange,提问作者Jasper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 09:24:28