TypeScript中JSON对象读取与覆写的问题排查
解决JSON文件读写中的异步问题与属性访问错误
一、最新问题:调用函数返回undefined
问题根源
- 异步函数返回值无法外部获取:
fs.readFile是异步IO操作,你的getReferenceNumber函数本身没有返回值,回调里的return仅在回调内部生效,外部调用时函数已执行完毕,因此拿到undefined。 - 对象属性访问语法错误:
data.productName会尝试访问对象中名为productName的固定属性,而非变量productName对应的动态属性名,需改用方括号语法data[productName]。
解决方案
方案1:Promise封装+async/await(推荐异步场景)
getReferenceNumber(productName: string): Promise<string | undefined> { return new Promise((resolve, reject) => { fs.readFile('./filepath.json', 'utf-8', (err, jsonString) => { if (err) { console.log(err); reject(err); return; } try { const data = JSON.parse(jsonString); resolve(data[productName]); } catch (err) { console.log("Error parsing JSON:", err); reject(err); } }); }); } // 调用方式 (async () => { const referenceNumber = await jsonHelper.getReferenceNumber("ProductA"); console.log(referenceNumber); // 输出"tbd" })();
方案2:同步读取(适合小文件场景)
getReferenceNumber(productName: string): string | undefined { try { const jsonString = fs.readFileSync('./filepath.json', 'utf-8'); const data = JSON.parse(jsonString); return data[productName]; } catch (err) { console.log(err); return undefined; } } // 调用方式 const referenceNumber = jsonHelper.getReferenceNumber("ProductA"); console.log(referenceNumber); // 输出"tbd"
二、原始问题:报错TypeError: data.id is not a function
问题根源
原始JSON结构中,每个产品对应一个数组,但你试图调用data.id(idNumber)——data对象中不存在名为id的方法,正确做法是遍历所有产品数组,匹配目标id。
修正后的读取函数
getReferenceNumber(idNumber: number): Promise<string | undefined> { return new Promise((resolve, reject) => { fs.readFile('./filepath.json', 'utf-8', (err, jsonString) => { if (err) { console.log(err); reject(err); return; } try { const data = JSON.parse(jsonString); // 遍历所有产品,查找匹配id的项 for (const productKey of Object.keys(data)) { const targetItem = data[productKey].find(item => item.id === idNumber); if (targetItem) { resolve(targetItem.rbq); return; } } resolve(undefined); // 未找到对应id } catch (err) { console.log("Error parsing JSON:", err); reject(err); } }); }); } // 调用方式 (async () => { const referenceNumber = await jsonHelper.getReferenceNumber(1); console.log(referenceNumber); // 输出"tbd" })();
修正后的更新函数
updateReferenceNumber(idNumber: number, newReference: string): Promise<void> { return new Promise((resolve, reject) => { fs.readFile('./filepath.json', 'utf-8', (err, jsonString) => { if (err) { console.log(err); reject(err); return; } try { const data = JSON.parse(jsonString); let found = false; // 遍历找到对应id的项 for (const productKey of Object.keys(data)) { const targetItem = data[productKey].find(item => item.id === idNumber); if (targetItem) { targetItem.rbq = newReference; found = true; break; } } if (!found) { console.log(`No item found with id: ${idNumber}`); resolve(); return; } // 格式化写入JSON,保留缩进 fs.writeFile('./filepath.json', JSON.stringify(data, null, 2), err => { if (err) { console.log(err); reject(err); } else { resolve(); } }); } catch (err) { console.log("Error parsing JSON:", err); reject(err); } }); }); } // 调用方式 (async () => { await jsonHelper.updateReferenceNumber(1, "new-tbd"); console.log("更新完成"); })();
内容的提问来源于stack exchange,提问作者Derek
相关产品推荐
相关产品推荐

