tslint - ¿Cómo verificar problemas de compilación de Typescript?
Toma la siguiente función flecha de Typescript:
/**
* Returns a probably unique component name.
*
* @param baseName a suggested name to make unique.
* @returns a probably unique name.
*/
export const getUniqueComponentName = (
baseName
): string => {
return baseName + Math.round(Math.random() * 10000000)
}
Cuando Typescript está configurado en tsconfig.json de la siguiente manera:
"noImplicitAny": true,
Esto resulta correctamente en un error de compilación:
[ts] El parámetro 'baseName' tiene implícitamente un tipo 'any'.
Visual Studio Code también es lo suficientemente inteligente como para informarte sobre este problema durante el desarrollo.
Mi objetivo es crear un hook de precommit en git que evite que tales errores terminen en el control de versiones. Intenté hacer esto con tslint, husky y lint-staged usando este script de npm:
"lint": "tslint --project tsconfig.json --config tslint.json"
Sin embargo, esto no resulta en que el error de compilación aparezca en tslint. Se ignora silenciosamente.
Luego intenté agregar una regla en tslint.json:
"typedef": [
true,
"arrow-parameter"
]
Aunque esto hizo que tslint se quejara, también comenzó a quejarse en funciones flecha anónimas donde el compilador tsc no se queja. En estas funciones flecha no debería ser necesario agregar tipos porque los tipos ya se habían establecido previamente en el ámbito principal (se infieren).
Así que básicamente, me gustaría que tslint se comportara igual que tsc en este caso. Cada vez que haya un error que causaría que la compilación falle (como la función de flecha mencionada anteriormente), me gustaría prevenir el commit, pero sin compilar realmente a Javascript. ¿Es esto posible?
Respuesta #1
Creo que tu mejor opción es ejecutar tsc --noEmit -p . y filtrar la salida para errores en los archivos modificados. Por ejemplo, guardé el siguiente script en tsc-some-files:
#!/bin/bash
declare -A include_files
for f in "$@"; do
include_files["${f#$PWD/}"]=1
done
node_modules/.bin/tsc --noEmit -p . | (
status=0
show_continuation=false
while IFS='' read -r line; do
case "$line" in
(' '*)
if $show_continuation; then
echo "$line" >&2
fi
;;
(*)
file="${line%%(*}"
if [ -n "${include_files["$file"]}" ]; then
show_continuation=true
echo "$line" >&2
status=1
else
show_continuation=false
fi
;;
esac
done
exit $status
)
y establecer ./tsc-some-files como mi comando lint-staged, y parecía funcionar. (Escribir esto en un lenguaje de programación distinto a bash, si se desea, se deja como un ejercicio para el lector.)
Ten en cuenta, sin embargo, que editar un archivo puede introducir un error en otro archivo (por ejemplo, si cambiaste el tipo de algo que el otro archivo está usando), así que te insto a limpiar tu proyecto de errores de TypeScript lo antes posible con cualquier truco necesario (siempre y cuando los marques para poder buscarlos después) y luego configurar tu hook para no permitir errores en todo el proyecto. De hecho, con respecto a noImplicitAny en particular, cuando migré un proyecto de JavaScript a TypeScript hace varios años, escribí un script que insertaba un any explícito en todos los lugares donde había un error de any implícito, y luego corregí los any explícitos a mi ritmo. Puedo compartir el script si estás interesado.
Respuesta #2
No tengo suficiente reputación para agregar esto como un comentario, pero cualquiera que esté recibiendo un error similar a
./scripts/ts-staged-files.sh: line 4:
src/ui/Components/Select/Select.tsx: division by 0
(error token is "/Components/Select/Select.tsx")
Hice esta pequeña modificación a la respuesta de Matt McCutchen para arreglarla.
#!/bin/bash
include_files=()
for f in "$@"; do
include_files+=("${f#$PWD/}")
done
