TypeScript中如何编写可修改对象指定属性的函数?
解决TypeScript动态修改对象属性的类型报错问题
这个问题我之前也踩过坑!核心原因有两个:一是TypeScript没法自动推断你传入的attributeToChange是item类型的合法属性名,二是直接用点语法访问动态属性时,TS会把attributeToChange当成一个字面量属性名(也就是认为你要访问名为attributeToChange的属性),而不是你传入的变量对应的属性,所以才会抛出“Property 'attributeToChange' does not exist on type 'item'”的错误。
先修正基础的代码问题
首先你的原代码里有几个小错误需要先调整:
- 接口名按照TypeScript规范应该首字母大写(比如
Item而非item) - 数组定义错误,
const arr = item[];应该写成const arr: Item[] = [];来指定类型 - 函数声明缺少
const,会导致变量泄漏到全局作用域
最直接的解决方案
给attributeToChange参数加上keyof Item类型约束,同时改用方括号语法访问动态属性:
// 修正接口命名和类型定义 interface Item { first: string; last: string; } // 正确定义Item类型的数组 const arr: Item[] = []; // 修正后的函数 const myFunc = (index: number, attributeToChange: keyof Item) => { // 用方括号访问动态属性,而非点语法 arr[index][attributeToChange] = "New first/last"; };
这里的keyof Item会自动推导为"first" | "last",确保你传入的attributeToChange只能是Item的合法属性名,TypeScript就会认可这个属性访问的合法性了。
更通用的泛型版本(推荐)
如果以后需要给其他类型的数组做类似操作,可以用泛型写一个通用函数,这样复用性更强,还能自动校验值的类型:
interface Item { first: string; last: string; } const arr: Item[] = []; // 泛型函数:支持任意对象类型的数组 const updateItemAttribute = <T, K extends keyof T>( array: T[], index: number, attribute: K, value: T[K] ) => { // 确保索引有效,避免运行时错误(可选但推荐) if (index >= 0 && index < array.length) { array[index][attribute] = value; } else { console.error("Invalid array index"); } }; // 使用示例:TS会自动校验属性名和值的类型 updateItemAttribute(arr, 0, "first", "Alice"); updateItemAttribute(arr, 0, "last", "Smith"); // 下面这行代码会报错,因为"age"不是Item的属性 // updateItemAttribute(arr, 0, "age", 30);
这个泛型版本的好处是:
- 支持任意类型的对象数组,不用为每个类型单独写函数
T[K]确保传入的value类型和目标属性的类型完全匹配,避免类型不兼容的错误- 加入了索引合法性检查,减少运行时崩溃的风险
内容的提问来源于stack exchange,提问作者blankface
相关产品推荐
相关产品推荐

