Si tuviera un archivo JavaScript index.js como este:

function foo(val) {
  console.log(val);
}

Y un archivo HTML index.html como este:

...
<script src="./index.js"></script>
<div id="container">
  <label>bar
    <input type="radio" name="radio" value="bar" onchange="foo(value);"/>
  </label>
  <label>baz
    <input type="radio" name="radio" value="baz" onchange="foo(value);"/>
  </label>
...

Esto registraría bar o baz cuando verifico un botón de radio.

Quiero llamar a foo(value) que se define en un archivo TypeScript index.ts como este:

let foo = (value: string): void => {
  console.log(value);
};

En index.html cambio <script src="./index.js"></script> a <script src="./src/index.ts"></script>, luego uso parcela para compilar la aplicación, pero el archivo compilado resultante no puede llamar a la función, registrando {{ X2}}.

Sé que, en teoría, el navegador no sabe nada sobre TypeScript y solo sabe JavaScript, pero después de compilar con parcela en mi directorio de destino veo un montón de archivos *js, uno de los cuales pensé que podría haber incluido el compilado { {X1}} función.

Entonces la pregunta es: ¿cómo puedo llamar a una función dentro de un archivo TS desde un atributo de cambio de entrada HTML como lo haría con un archivo JS?

Por último, pero no menos importante: para crear mi aplicación, invoco parcel start (o incluso parcel run build), y mi package.json se ve así:

{
  "name": "app_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start:build": "tsc -w",
    "start": "parcel index.html",
    "build": "parcel build --public-url . index.html"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
  },
  "devDependencies": {
    "parcel-bundler": "^1.12.4",
    "typescript": "^3.7.5"
  }
}
0
umbe1987 18 feb. 2020 a las 16:34

2 respuestas

La mejor respuesta

El problema:

Las herramientas como Parcel y Webpack que agrupan sus js envuelven todos sus módulos en IIFE, por lo tanto, después de que Parcel procese su index.ts la función foo ya no es global y ya no puede acceder a ella desde su archivo html. . Sin procesamiento (como en este caso: <script src="./index.js"></script>) foo es global.

Solución:

Hacer foo global.

// index.ts
function foo(val: string) {
  console.log(val);
}

window.foo = foo;

Codesandbox

3
Johnny Zabala 18 feb. 2020 a las 15:00

En lugar de hacer referencia a index.ts directamente desde su archivo index.html, intente señalar los archivos compilados en /dist así:

<script src="dist/index.js"></script>

Como ha indicado correctamente, TypeScript es simplemente un superconjunto de JavaScript y su navegador no puede interpretarlo, solo después de compilarlo en JavaScript.

0
JasonK 18 feb. 2020 a las 13:38