如何根据方法参数动态选择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'
踩坑记录
- 直接用索引赋值时,触发错误:
this[parameterName] = value;
No index signature with a parameter of type 'string' was found on type 'Person'.
- 用
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
相关产品推荐
相关产品推荐

