如何修改TypeScript中JSONValue类型的属性值?
问题分析与解决方案
先模拟你大概率的原始代码(方便对应问题):
type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue }; interface Data { values: JSONValue; } const d: Data = { values: { first: 1 } }; d.values["first"] = 2; // 触发类型错误
报错原因很直接:JSONValue是联合类型,TypeScript无法确定d.values到底是对象、数组、字符串还是其他类型,自然不允许直接用字符串索引修改值。
下面是三种可行的解决方式:
方案一:明确Data接口的values类型(推荐)
直接把Data里values的类型从宽泛的JSONValue改成对象类型,让TypeScript明确它是可索引的:
// 方式1:用Record表示任意字符串键对应JSONValue值 interface Data { values: Record<string, JSONValue>; } // 方式2:如果知道具体键名,定义更精确的类型(类型检查更严格) interface Data { values: { first?: number; // 可以添加其他明确的键值对 }; }
修改后直接执行d.values["first"] = 2;就不会报错了。
方案二:类型断言(适合无法修改Data接口的场景)
如果不能修改Data接口,可以通过类型断言告诉TypeScript你确定d.values是对象类型:
// 通用对象断言 (d.values as Record<string, JSONValue>)["first"] = 2; // 更精确的断言(如果确定first键对应number类型) (d.values as { first: number })["first"] = 2;
注意:断言是“强行为类型兜底”,如果运行时d.values实际不是对象,会触发报错,所以要确保你对值的类型有绝对把握。
方案三:类型守卫(最安全)
写一个类型守卫函数,先判断d.values是否为对象,再安全赋值:
function isJsonObject(value: JSONValue): value is { [key: string]: JSONValue } { return typeof value === 'object' && value !== null && !Array.isArray(value); } if (isJsonObject(d.values)) { d.values["first"] = 2; // 这里TypeScript会自动缩小类型范围,确保安全 }
这种方式不会有运行时风险,TypeScript会在守卫生效的代码块内自动识别d.values的对象类型。
内容的提问来源于stack exchange,提问作者saydiva
相关产品推荐
相关产品推荐

