web-dev-qa-db-fra.com

Comment lint pour les problèmes de compilation TypeScript?

Prenez la fonction de flèche TypeScript suivante:

/**
 * 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)
}

Lorsque TypeScript est configuré dans tsconfig.json en tant que tel:

"noImplicitAny": true,

Cela entraîne correctement une erreur de compilation:

[ts] Le paramètre 'baseName' a implicitement un type 'quelconque'.

Visual Studio Code est également suffisamment intelligent pour vous informer de ce problème pendant le développement.

Mon objectif est de créer un hook git pré-engagé qui empêche de telles erreurs de se retrouver dans le contrôle de version. J'ai essayé de faire cela avec tslint, husky et lint-staged en utilisant ce npm script:

"lint": "tslint --project tsconfig.json --config tslint.json"

Cependant, cela n'entraîne pas l'erreur de compilation par tslint. Il est ignoré silencieusement.

J'ai ensuite essayé d'ajouter une règle dans tslint.json:

"typedef": [
      true,
      "arrow-parameter"
    ]

Bien que cela ait amené Tslint à se plaindre, il a également commencé à se plaindre dans les fonctions de flèche anonymes où le compilateur tsc ne se plaint pas. Dans ces fonctions de flèche, il ne devrait pas être nécessaire d’ajouter des types car ceux-ci étaient déjà définis dans la portée parente (ils sont inférés). 

Donc, fondamentalement, j'aimerais que tslint se comporte comme tsc dans ce cas. En cas d'erreur pouvant entraîner l'échec de la compilation (telle que la fonction de flèche ci-dessus), j'aimerais empêcher la validation, mais sans compiler en Javascript. Est-ce possible?

9
Tom

Je pense que votre meilleur pari est d'exécuter tsc --noEmit -p . et de filtrer la sortie pour les erreurs dans les fichiers modifiés. Par exemple, j'ai enregistré le script suivant dans 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
)

et définir ./tsc-some-files comme ma commande lint-staged, et cela a semblé fonctionner. (L'écriture dans un langage de programmation autre que bash, si vous le souhaitez, reste un exercice pour le lecteur.)

Gardez à l'esprit que l'édition d'un fichier peut introduire une erreur dans un autre fichier (par exemple, si vous modifiez le type de quelque chose utilisé par l'autre fichier), je vous encourage donc vivement à nettoyer votre projet des erreurs TypeScript dès que possible. hacks nécessaires (tant que vous les marquez pour pouvoir les rechercher plus tard), puis configurez votre hook pour qu'il ne nécessite aucune erreur dans l'ensemble du projet. En fait, concernant noImplicitAny en particulier, lorsque j'ai migré un projet JavaScript vers TypeScript il y a plusieurs années, j'ai écrit un script qui insérait une any explicite partout où il y avait une erreur implicite any, puis j'ai corrigé les any explicites à ma guise. Je peux partager le script si cela vous intéresse.

6
Matt McCutchen

Je n'ai pas assez de réputation pour ajouter cela en tant que commentaire, mais toute personne qui reçoit une erreur similaire à

./scripts/ts-staged-files.sh: line 4: 
   src/ui/Components/Select/Select.tsx: division by 0 
  (error token is "/Components/Select/Select.tsx")

J'ai apporté cette petite modification à la réponse de Matt McCutchen pour y remédier.

#!/bin/bash

include_files=()

for f in "$@"; do
  include_files+=("${f#$PWD/}")
done
0
jmmendez