¿Por qué TypeScript no vive en el vacío?
\nCuando escribimos en TypeScript, nos acostumbramos a su rigor, autocompletado y genéricos. Pero tarde o temprano, todo desarrollador se enfrenta a la pregunta: "¿Y si necesito llamar código en Python, C++ o Go?". ¿Acaso hay que reescribir todo el proyecto?
\nLa buena noticia: TypeScript no es una isla aislada. Sabe cómo llevarse bien con otros lenguajes a través de módulos nativos, WebAssembly, gRPC e incluso puentes HTTP comunes. En este artículo, analizaremos tres escenarios reales de integración de TypeScript con otros lenguajes. Aprenderá cómo unir el frontend, el backend y la computación de alto rendimiento en una sola pila.
\n\nEscenario 1: TypeScript + Python — ciencia de datos con esteroides
\nPython es el rey del aprendizaje automático y el análisis de datos. Pero su debilidad son las interfaces web. TypeScript, por el contrario, funciona de manera brillante en el navegador y en el servidor. Es lógico combinar sus fuerzas.
\n\nMétodo A: Microservicio HTTP (el más simple)
\nLa forma más obvia es iniciar un servidor Python (por ejemplo, FastAPI) y llamarlo desde TypeScript mediante fetch.
\nPython (backend.py):
\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nimport joblib\n\napp = FastAPI()\nmodel = joblib.load('model.pkl')\n\nclass InputData(BaseModel):\n features: list[float]\n\n@app.post("/predict")\ndef predict(data: InputData):\n result = model.predict([data.features])\n return {"prediction": result.tolist()}\n\nTypeScript (frontend.ts):
\ninterface PredictionResponse {\n prediction: number[];\n}\n\nasync function getPrediction(features: number[]): Promise<number[]> {\n const response = await fetch('http://localhost:8000/predict', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ features })\n });\n \n if (!response.ok) throw new Error('Error de predicción');\n \n const data: PredictionResponse = await response.json();\n return data.prediction;\n}\n\n// Uso\ngetPrediction([1.2, 3.4, 5.6])\n .then(pred => console.log('Resultado:', pred))\n .catch(err => console.error(err));\n\n\nMétodo B: Scripts de Python mediante child_process (para backend)
\nSi no necesita un servidor separado, puede ejecutar Python directamente desde Node.js. Esto es útil para tareas puntuales: procesamiento de imágenes, generación de informes.
\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execPromise = promisify(exec);\n\nasync function runPythonScript(scriptPath: string, args: string[]): Promise<string> {\n const command = `python3 ${scriptPath} ${args.join(' ')}`;\n const { stdout, stderr } = await execPromise(command);\n \n if (stderr) throw new Error(`Error de Python: ${stderr}`);\n return stdout.trim();\n}\n\n// Ejemplo: pasamos JSON a Python\nconst result = await runPythonScript('./analyze.py', ['--data', '{"value": 42}']);\nconsole.log('Python respondió:', result);\n\nImportante: este enfoque es más lento que un microservicio, pero no requiere configurar un servidor separado. Es adecuado para prototipos y CI/CD.
\n\nEscenario 2: TypeScript + C++ — velocidad al límite de la fantasía
\nCuando se necesita procesar video, audio o criptografía, Python puede no ser suficiente. Aquí entra en juego C++ y su poderoso aliado: WebAssembly (WASM).
\n\nCompilación de C++ a WASM y llamada desde TypeScript
\nSupongamos que tenemos una función simple en C++ que acelera la multiplicación de matrices:
\n// matrix.cpp\nextern "C" {\n void multiply_matrices(float* a, float* b, float* result, int size) {\n for (int i = 0; i < size; i++) {\n for (int j = 0; j < size; j++) {\n float sum = 0.0f;\n for (int k = 0; k < size; k++) {\n sum += a[i * size + k] * b[k * size + j];\n