如何在TypeScript中替换JSON读取的模板字符串变量?
解决方案
要实现无需提前知晓变量结构的模板字符串替换,核心是动态解析变量路径并递归遍历JSON对象,具体实现步骤如下:
1. 实现嵌套属性取值工具函数
这个函数可以根据.分隔的路径字符串,从变量对象中逐层取出对应的值,无需提前知道对象结构:
function getNestedValue(obj: Record<string, any>, path: string): any { return path.split('.').reduce((current, key) => { return current?.[key] ?? ''; // 路径不存在时返回空字符串,可按需改为保留原模板或抛错 }, obj); }
2. 递归遍历JSON并替换模板变量
通过递归处理JSON中的所有字符串值,匹配${xxx}格式的模板并替换为对应变量值,支持嵌套对象和数组:
function replaceTemplateVars(obj: any, vars: Record<string, any>): any { // 处理数组元素 if (Array.isArray(obj)) { return obj.map(item => replaceTemplateVars(item, vars)); } // 处理嵌套对象 if (typeof obj === 'object' && obj !== null) { const result: Record<string, any> = {}; for (const key in obj) { result[key] = replaceTemplateVars(obj[key], vars); } return result; } // 处理字符串模板替换 if (typeof obj === 'string') { return obj.replace(/\${([^}]+)}/g, (_, path) => { return getNestedValue(vars, path.trim()); }); } // 非字符串类型直接返回 return obj; }
3. 使用示例
// 读取后的JSON配置对象 const config = { "log": "logfile-${profile}", "user": "user-${profile.name}", "id": "id-${profile.id}", "nested": { "path": "data-${settings.path.root}" }, "array": ["item-${profile.id}", "value-${settings.env}"] }; // 实际的环境变量对象(支持任意层级) const envVars = { profile: { name: "admin", id: "12345" }, settings: { path: { root: "/var/data" }, env: "production" } }; // 执行替换 const finalConfig = replaceTemplateVars(config, envVars); console.log(finalConfig);
执行后输出结果:
{ log: 'logfile-admin', user: 'user-admin', id: 'id-12345', nested: { path: 'data-/var/data' }, array: [ 'item-12345', 'value-production' ] }
自定义调整说明
- 如果需要在变量路径不存在时保留原模板字符串,可将
getNestedValue中的?? ''改为?? match。 - 若要对不存在的路径抛出错误,可在
reduce中判断current[key]不存在时抛出Error。
内容的提问来源于stack exchange,提问作者omer keynan
相关产品推荐
相关产品推荐

