Guía
Tipos
Los props de los componentes, los manejadores y los ref se comprueban con ascua-check, que devuelve cada error a tu archivo y a su línea.
El problema
Para TypeScript, una plantilla es una cadena y lo que va en sus huecos es
unknown. Esto compila sin quejarse:
function Tarjeta(props: { titulo: string }) { … }
view`<main><Tarjeta titulo=${42}/></main>`; // titulo es un stringEl editor tampoco ayuda: dentro de una plantilla no hay autocompletado de props ni errores en rojo.
ascua-check
Lo que sale del compilador sí es TypeScript tipado: esa etiqueta se
convierte en Tarjeta({ titulo: 42 }), y ahí TypeScript encuentra el error por
su cuenta. ascua-check compila el proyecto, lo pasa por tsc y devuelve cada
error a tu archivo y a su línea:
stil add -D ascua-check
stil exec ascua-checksrc/panel.ts:69:22 - error TS2322: Type 'number' is not assignable to type 'string'.
69 <Metrica etiqueta=${7} valor=${() => pesos(facturado())}/>
~
✗ 1 error en 1 archivoSe usa como tsc --noEmit: en un script del package.json y en el CI.
{
"scripts": {
"check": "ascua-check"
}
}Qué comprueba
| En la plantilla | Qué se comprueba |
|---|---|
<Tarjeta titulo=${42}/> |
El tipo de cada prop. |
<Metrica etiqueta="x"/> |
Los props obligatorios que faltan. |
onclick=${(e: MouseEvent) => …} |
Que el manejador acepte el evento: un click es un MouseEvent, un keydown un KeyboardEvent. |
<input ref=${(n: HTMLInputElement) => …}> |
Que el ref reciba el elemento de su etiqueta. |
prop:value=${() => …}, class=${…} |
Que la expresión sea válida. |
| Todo lo demás del archivo | Lo mismo que tsc. |
Los errores de dentro de una plantilla caen en la línea donde se escribió
el elemento, el atributo o el prop, no en la del view: si una etiqueta ocupa
varias líneas, cada prop tiene la suya.
Con qué TypeScript
Con el del proyecto, sea el 5 o el 7. ascua-check no usa la API de
TypeScript —cambia entre versiones, y en la 7 todavía no es estable—, sino el
binario tsc y su salida, que no cambian.
Tu tsconfig.json se respeta entero: extends, include, paths y las
opciones de comprobación. ascua-check le pide a tsc la configuración ya
resuelta y genera otra que la extiende y apunta a la copia compilada.
Cómo funciona
tsc --showConfigresuelve tu configuración, con la lista exacta de archivos.- El proyecto se copia a
.ascua-check/, con las plantillas compiladas y su source map. - Un tsconfig nuevo extiende el tuyo y apunta a la copia; los
pathsque señalaban a tu código se trasladan a su sitio en ella. - Se ejecuta tu
tsc, y cada error vuelve a tu archivo: la línea, por el source map; la columna, buscando en tu línea lo mismo que señalaba el error. - La copia se borra. Con
--conservarse queda, para ver qué comprobótsc.
En el editor
ascua-ts-plugin lleva lo mismo al editor, mientras escribes:
- los errores de tipos de las plantillas, subrayados donde están;
- autocompletado de props dentro de la etiqueta de un componente, con los obligatorios primero y sin los que ya escribiste;
- autocompletado del HTML: después de
<, las etiquetas y tus componentes; dentro de una etiqueta, sus atributos y los globales, los eventos (oninput,onkeydown…),prop:con las propiedades que se pueden escribir en ese elemento,class:yref. Con el valor ya puesto: comillas para un atributo,${}para un evento; - ir a la definición desde
<Tarjetahasta la función; - la firma del componente al pasar por encima de su etiqueta;
- los errores de sintaxis de una plantilla, en su línea.
stil add -D ascua-ts-plugin{
"compilerOptions": {
"plugins": [{ "name": "ascua-ts-plugin" }]
}
}Cuidado: el editor tiene que usar la versión de TypeScript del
proyecto. tsserver busca los plugins junto al TypeScript que ejecuta; con
el que trae el editor no lo encuentra. En VS Code: TypeScript: Select
TypeScript Version → Use Workspace Version.
Funciona con TypeScript 5 y 6, que son los que tienen tsserver. TypeScript 7,
el nativo, todavía no admite plugins: un proyecto que compila con él necesita
además typescript@6 para el editor. ascua-check sirve con los tres.
Lo que falta
- La columna de un error se encuentra buscando en tu línea el nombre que señala TypeScript: casi siempre es el prop exacto, y si no aparece, el subrayado empieza donde empieza la etiqueta.