Python을 배워보자

TypeScript 파일 파싱하기: Node.js와 Python 연동으로 const 객체를 Python 딕셔너리로 변환하기

_Blue_Sky_ 2025. 3. 2. 12:59
728x90

TypeScript 파일을 파싱하기 위해 외부 라이브러리를 사용하는 예제를 보여드리겠습니다. 여기서는 typescript 공식 패키지를 사용하여 TS 파일을 분석하고 const 변수의 객체 초기값을 Python 딕셔너리로 변환하는 방법을 설명합니다.
먼저, Python에서 TypeScript를 사용하려면 pytypescripttypescript를 직접 호출할 수 있는 환경이 필요하지만, Python에서 직접 TS 파서를 호출하는 대신 nodetypescript를 활용한 방법을 사용하겠습니다. 아래는 이를 구현한 예제입니다.
준비 단계
  1. Node.jsTypeScript 설치가 필요합니다:
    bash
     
    npm install -g typescript
  2. Python에서 Node.js 스크립트를 호출하거나, ts-node를 사용할 수 있습니다:
    bash
     
    npm install -g ts-node
방법 1: TypeScript 공식 패키지 사용 (Node.js + Python 연동)
TypeScript 파일을 파싱하기 위해 Node.js 스크립트를 작성하고, Python에서 이를 호출합니다.
1. Node.js 스크립트 (parse_ts.js)
javascript
 
const ts = require('typescript');
const fs = require('fs');

function parseTSFile(filePath) {
    const content = fs.readFileSync(filePath, 'utf-8');
    const sourceFile = ts.createSourceFile(
        filePath,
        content,
        ts.ScriptTarget.Latest,
        true
    );

    const result = {};

    function visit(node) {
        if (ts.isVariableStatement(node)) {
            node.declarationList.declarations.forEach(decl => {
                if (ts.isVariableDeclaration(decl) && decl.initializer) {
                    const name = decl.name.getText();
                    if (ts.isObjectLiteralExpression(decl.initializer)) {
                        const obj = {};
                        decl.initializer.properties.forEach(prop => {
                            if (ts.isPropertyAssignment(prop)) {
                                const key = prop.name.getText();
                                const value = evaluateValue(prop.initializer);
                                obj[key] = value;
                            }
                        });
                        result[name] = obj;
                    }
                }
            });
        }
        ts.forEachChild(node, visit);
    }

    function evaluateValue(node) {
        if (ts.isStringLiteral(node)) return node.text;
        if (ts.isNumericLiteral(node)) return Number(node.text);
        if (node.kind === ts.SyntaxKind.TrueKeyword) return true;
        if (node.kind === ts.SyntaxKind.FalseKeyword) return false;
        return null; // 기타 타입은 생략
    }

    visit(sourceFile);
    console.log(JSON.stringify(result));
}

parseTSFile(process.argv[2]);
2. Python 코드
python
 
import subprocess
import json

def parse_ts_with_typescript(file_path: str) -> dict:
    """
    TypeScript 파일을 파싱하여 const 변수의 객체를 딕셔너리로 반환
    """
    try:
        # Node.js 스크립트 실행
        result = subprocess.run(
            ['node', 'parse_ts.js', file_path],
            capture_output=True,
            text=True,
            check=True
        )
        
        # 결과를 JSON으로 파싱
        parsed_data = json.loads(result.stdout)
        return parsed_data
        
    except subprocess.CalledProcessError as e:
        print(f"파싱 중 오류 발생: {e.stderr}")
        return {}
    except Exception as e:
        print(f"오류 발생: {str(e)}")
        return {}

# 사용 예시
if __name__ == "__main__":
    file_path = "example.ts"
    """
    // example.ts 내용
    const config = {
        apiKey: "abc123",
        timeout: 5000,
        isActive: true,
        mode: 'production'
    };
    const user = {
        name: "John",
        age: 30
    };
    """
    
    result = parse_ts_with_typescript(file_path)
    
    # 결과 출력
    for var_name, obj_dict in result.items():
        print(f"{var_name}:")
        for key, value in obj_dict.items():
            print(f"  {key}: {value} ({type(value)})")
 

 

방법 2: ts_parser 사용 (Python 패키지 활용)

ts_parser라는 Python 패키지가 있다면 이를 사용할 수 있습니다. 하지만 현재 기준으로 ts_parser는 널리 알려진 패키지가 아니므로, 비슷한 기능을 제공하는 py-ts-parser나 직접 TS AST를 다루는 라이브러리를 가정하여 예제를 작성하겠습니다.
설치 (가정)
bash
 
pip install py-ts-parser  # 가상의 패키지
 
728x90
 
Python 코드
python
 
# 참고: 이 코드는 가상의 ts_parser 패키지를 가정합니다.
from ts_parser import TypeScriptParser  # 가상의 모듈

def parse_ts_with_ts_parser(file_path: str) -> dict:
    """
    ts_parser를 사용해 TS 파일에서 const 객체를 딕셔너리로 변환
    """
    parser = TypeScriptParser()
    result = {}
    
    try:
        # TS 파일 파싱
        ast = parser.parse_file(file_path)
        
        # AST 순회
        for node in ast.nodes:
            if node.type == 'VariableStatement':
                for decl in node.declarations:
                    if decl.initializer and decl.initializer.type == 'ObjectLiteral':
                        var_name = decl.name
                        obj_dict = {}
                        for prop in decl.initializer.properties:
                            key = prop.name
                            value = evaluate_ts_value(prop.value)
                            obj_dict[key] = value
                        result[var_name] = obj_dict
                        
        return result
    
    except Exception as e:
        print(f"파싱 오류: {str(e)}")
        return {}

def evaluate_ts_value(node) -> any:
    """TS 값 노드를 Python 값으로 변환"""
    if node.type == 'StringLiteral':
        return node.value
    elif node.type == 'NumericLiteral':
        return int(node.value)
    elif node.type == 'BooleanLiteral':
        return node.value == 'true'
    return None

# 사용 예시
file_path = "example.ts"
result = parse_ts_with_ts_parser(file_path)
print(result)
실제 환경에서 주의할 점
  1. 의존성: 첫 번째 방법은 Node.js와 TypeScript 패키지가 설치되어 있어야 합니다.
  2. 제한사항: 위 코드는 단순한 객체 리터럴만 처리하며, 중첩 객체, 배열, 함수 등은 추가 작업이 필요합니다.
  3. 대안: ts_parser 같은 Python 전용 TS 파서가 없다면, esprima (JavaScript 파서)나 acorn을 Python에서 호출하는 것도 고려할 수 있습니다.
실행 결과 예시
example.ts 파일이 위에 주어진 내용이라면 출력은 다음과 같습니다:
 
config:
  apiKey: abc123 (<class 'str'>)
  timeout: 5000 (<class 'int'>)
  isActive: True (<class 'bool'>)
  mode: production (<class 'str'>)
user:
  name: John (<class 'str'>)
  age: 30 (<class 'int'>)
첫 번째 방법(typescript + Node.js)이 더 정확하고 안정적이며, TypeScript의 공식 AST를 활용하므로 추천드립니다. 환경에 맞게 조정해서 사용하세요!
728x90