从JavaScript变量声明字符串提取变量值的TypeScript安全方案
Hey there! Totally get why you want to steer clear of unsafe methods like eval or new Function—they’re massive security risks (especially if the string comes from untrusted sources) and TypeScript rightly discourages their use. Here are a couple of robust, safe approaches to pull those exp, test, and test2 values:
1. Use a JavaScript AST Parser (Recommended)
The most reliable way is to parse the string into an Abstract Syntax Tree (AST) using a trusted parser library, then traverse the tree to locate your target variables. This handles all edge cases (like strings with escaped quotes, numeric values, booleans, etc.) that regex would struggle with.
Example with acorn
acorn is a lightweight, widely adopted JavaScript parser. Here’s how to use it:
First, install the package:
npm install acorn acorn-walk --save-dev
Then write your TypeScript code to parse and extract variables:
import * as acorn from 'acorn'; import * as walk from 'acorn-walk'; const abc = `const exp = 'hello world'; const test = 42; const test2 = true;`; // Parse the string into an AST const ast = acorn.parse(abc, { ecmaVersion: 'latest' }); // Object to store extracted values const extractedValues: Record<string, any> = {}; // Traverse the AST to find variable declarations walk.simple(ast, { VariableDeclaration(node) { node.declarations.forEach(declaration => { const varName = declaration.id.name; // Check if it's one of our target variables if (['exp', 'test', 'test2'].includes(varName)) { // Extract the value based on the literal type if (declaration.init?.type === 'Literal') { extractedValues[varName] = declaration.init.value; } // Add handling for other types (objects, arrays) if needed } }); } }); console.log(extractedValues); // Output: { exp: 'hello world', test: 42, test2: true }
Alternative: @babel/parser
If you’re already using Babel in your project, @babel/parser (formerly babylon) works seamlessly too. The approach is identical—parse to AST, then traverse it using @babel/traverse.
2. Regex (Only for Simple, Predictable Code)
If your variable declarations are extremely straightforward (no escaped quotes, no complex values like objects/arrays), regex can be a quick fix. But be warned: regex breaks easily if the input string varies even slightly.
Example regex approach:
const abc = `const exp = 'hello world'; const test = 42; const test2 = true;`; const extractVariable = (name: string): any => { const regex = new RegExp(`const ${name} = ([^;]+);`); const match = abc.match(regex); if (!match) return undefined; // Parse the value (handle strings, numbers, booleans) const valueStr = match[1].trim(); if (valueStr.startsWith("'") && valueStr.endsWith("'")) { return valueStr.slice(1, -1); } if (valueStr === 'true') return true; if (valueStr === 'false') return false; const num = Number(valueStr); return isNaN(num) ? valueStr : num; }; const exp = extractVariable('exp'); const test = extractVariable('test'); const test2 = extractVariable('test2'); console.log(exp, test, test2); // 'hello world' 42 true
Just remember: regex is no replacement for a proper parser when dealing with real-world JavaScript code.
内容的提问来源于stack exchange,提问作者rossanmol

