Codage TypeScript
Workflow
-
S'orienter. Lire les sources de vérité du projet avant d'écrire :
package.json(type,engines,packageManager,exports,scripts, versions majeures installées), le lockfile, chaquetsconfig*.jsonavec sa chaîneextends, le workspace racine, les configurations du framework, du lint et du format (pnpm-workspace.yaml,turbo.json,next.config.ts,biome.json,.oxlintrc.json), et le CI pour les commandes de vérification canoniques. Exécutertsc --showConfigpour résoudre la chaîneextends; il omet les options laissées à leur valeur par défaut, donc les lire depuisreferences/modules.md(TypeScript 6 et 7 les ont modifiées). Lire le module que vous modifiez et ses voisins ; réutiliser leurs helpers, types d'erreur, schémas et motifs. Terminé quand : vous pouvez nommer le gestionnaire de paquets, la version majeure de TypeScript,moduleetmoduleResolution, les flags de sévérité au-delà destrict(noUncheckedIndexedAccess,exactOptionalPropertyTypes,erasableSyntaxOnly), la chaîne d'outils de lint et de format, et les commandes de vérification du projet. -
Modéliser les types. Concevoir les données avant le contrôle de flux, en suivant Types. Entrée depuis l'extérieur du processus : lire
references/zod.md. Modification de l'API publique d'un paquet : lirereferences/api.md. Terminé quand : chaque invariant sur lequel repose la modification est encodé dans un type, et chaque valeur traversant une frontière de confiance est analysée par un schéma avant utilisation. -
Implémenter en boucle serrée. Travailler par petites étapes et exécuter
tsc --noEmit(tsc -bavec des références de projet) après chacune. Lire l'intégralité du diagnostic ; son code (TS2742) est la clé de recherche dans les tableaux dereferences/modules.mdetreferences/types.md. Pour l'API d'une dépendance, lire son.d.tsdansnode_modules/<pkg>/à la version installée. Correction de bug : écrire d'abord le test de régression et le voir passer au rouge. Terminé quand : la modification passe la vérification de types sans nouveau diagnostic, et tout test de régression est passé au rouge avant la correction et au vert après. -
Vérifier. Exécuter les commandes du projet de l'étape 1 via son gestionnaire de paquets (
pnpm exec,npx,bunx) ; sinon, pour la chaîne d'outils utilisée par le projet :tsc --noEmit # tsc -b quand tsconfig.json ne liste que des références biome ci # Biome oxfmt --check && oxlint --type-aware --deny-warnings # oxlint + oxfmt vitest run --typecheck # ou le runner de test du projet- Un
tsconfig.jsonracine avec"files": []etreferencesfait quetsc --noEmitne vérifie rien ; utilisertsc -b. Dans un workspace sans tsconfig racine, exécuter les vérifications par paquet via le runner de tâches (turbo run check-types test). - Garder
tscdans la boucle avec chaque linter : l'inférence de types de Biome et les règles type-aware d'oxlint le complètent, ne le remplacent jamais. - Échecs de formatage : appliquer le formateur (
biome check --write,oxfmt) au lieu de modifier à la main. - Corriger les diagnostics à la source. Quand la suppression est appropriée, la limiter à une ligne et donner la raison :
// biome-ignore lint/<group>/<rule>: raison,// oxlint-disable-next-line <rule> -- raison,// @ts-expect-error raison. - Configuration de lint ou de format touchée : la vérifier par rapport à
references/lints.md, puis exécuter le linter et le formateur sur l'ensemble du dépôt, pas seulement sur les fichiers modifiés. - API publique d'un paquet publié touchée : exécuter
references/api.md. Terminé quand : chaque commande se termine par 0, les lignes que vous avez modifiées ne lèvent aucun avertissement, et chaque nouvelle suppression porte une raison.
- Un
-
Auto-relecture du diff. Relire l'intégralité du
git diff(git add -A && git diff --cachedquand les fichiers sont nouveaux), pas votre mémoire de celui-ci, en le confrontant aux Règles et aux règles de chaque fichier de référence dont la branche du diff touche. Terminé quand : chaque hunk est requis par la tâche,console.log,debugger,.onlyet le code commenté ont disparu, les commentaires de doc correspondent au comportement, et chaque règle applicable s'applique à chaque hunk.
Relecture du code de quelqu'un d'autre : exécuter l'étape 1, exécuter les commandes de l'étape 4 quand vous le pouvez, puis appliquer l'étape 5 à son diff. Rapporter chaque constatation comme path:line, la règle et la correction.
Règles
Types
- Réduire avec preuve :
typeof,instanceof,in, une vérification de discriminant, un prédicat de type ou une analyse de schéma.any, le!non nul etas Tsont interdits, même dans les tests ;as constetsatisfiesrestent autorisés. Quand les types d'une bibliothèque sont erronés, les corriger à la source avec une augmentation de module (references/types.md). - Rendre les états illégaux ir représentables : une union discriminée avec un champ
kindlittéral, plutôt que des flagsbooleanplus des champs optionnels. Marquer les IDs, unités et valeurs validées via un schéma (z.string().brand<"UserId">()) ou un prédicat de type, jamais avecas. - Analyser, ne pas valider :
JSON.parse,Response.json(), les variables d'environnement, le stockage, les paramètres d'URL et les donnéespostMessagesontunknownjusqu'à ce qu'un schéma Zod les analyse à la frontière ; passer le type analysé vers l'intérieur. - Basculer exhaustivement sur les unions que vous possédez : terminer par
default: x satisfies never; throw new Error(...), ou mapper avec une rechercheRecord<Union, V>qui échoue à la compilation quand un membre est ajouté. - L'accès indexé est
T | undefinedsousnoUncheckedIndexedAccess: gérer leundefined(garde,?? fallback,for...of) au lieu de l'affirmer. - Les fonctions exportées déclarent leur type de retour ; les locales restent inférées.
interfacepour les formes d'objet,extendsplutôt que les intersections&;typepour les unions, les types mappés et conditionnels.- Accepter
readonly T[]etReadonly<T>pour les entrées que la fonction ne mute pas. - Une union de littéraux de chaîne ou un objet
as const, plutôt queenumet les namespaces avec du code runtime (les deux sont interdits souserasableSyntaxOnly).
Erreurs et asynchrone
- Les échecs attendus que l'appelant doit gérer retournent un résultat discriminé ; les bugs et les états irrécupérables lèvent une sous-classe d'
Erroravec{ cause }. Détails :references/errors.md. - Chaque promesse est attendue (
await), retournée ou passée à un gestionnaire qui observe son rejet.
Idiomes actuels
Les données d'entraînement sont antérieures à TypeScript 6 et 7 : TypeScript 7 est le compilateur en Go, strict est activé par défaut, types vaut [] par défaut, et baseUrl, outFile, target: "ES5" et moduleResolution: "node10" sont supprimés (references/modules.md). Préférer la forme actuelle, y compris les API de la bibliothèque standard selon le lib niveau, quand les versions installées le permettent. Quand une référence est en désaccord avec le .d.ts ou le CHANGELOG du paquet installé, la version installée l'emporte.
| Préférer | Plutôt que | Depuis |
|---|---|---|
const config = { ... } satisfies Config | const config: Config (élargit), as Config | 4.9 |
function f<const T>(x: T) | as const à chaque site d'appel | 5.0 |
import type { T } avec verbatimModuleSyntax | importsNotUsedAsValues (supprimé) | 5.0 |
using / await using avec [Symbol.dispose] | try / finally nettoyage | 5.2, lib esnext |
import data from "./d.json" with { type: "json" } | assert { type: "json" } (erreur depuis 6.0) | 5.3 |
NoInfer<T> | bloqueurs d'inférence T & {} | 5.4 |
prédicats inférés : xs.filter((x) => x !== undefined) | gardes écrits à la main (x): x is T => | 5.5 |
Documentation et commentaires
- Les éléments exportés reçoivent des docs
/** */décrivant le contrat :@throwspour les erreurs levées,@deprecatednommant le remplacement,@examplequand l'utilisation n'est pas évidente d'après la signature.
Dépendances
- Réutiliser ce que
package.jsonliste déjà, et préférer la plateforme quand elle couvre le besoin :fetch,structuredClone,crypto.randomUUID,AbortSignal.timeout, les builtins préfixés parnode:. - Ajouter avec le gestionnaire de paquets du projet, en épinglant les
@types/*à la version majeure du paquet runtime (@types/node: le Node le plus bas dansengines).
Références
Charger celle qui correspond à la branche sur laquelle vous travaillez :
references/types.md: génériques, types conditionnels et mappés, prédicats de type, augmentation de module, erreurs au niveau des types.references/errors.md: définition des types d'erreur, unions de résultat,cause, frontières d'erreur entre couches.references/async.md: promesses, annulation avecAbortSignal, concurrence,using, itération asynchrone.references/modules.md:tsconfig.json,package.json, résolution de modules, ESM et CommonJS, migration TypeScript 6 et 7, erreurs de configuration.references/zod.md: analyse d'entrées non fiables, schémas, API Zod 4.references/react.md: composants React, hooks, API React 19, React Compiler.references/nextjs.md: App Router Next.js, Server Components et Functions,"use cache", types de routes.references/recharts.md: graphiques Recharts,dataKeytypé, tooltips et formes personnalisés, dimensionnement des graphiques.references/lints.md: configuration ou modification de Biome, oxlint ou oxfmt.references/testing.md: écriture de tests, tests de types, tests de composants React, mocks.references/perf.md: vérification de types lente, latence de l'éditeur, taille du bundle, chemin chaud mesuré.references/api.md: conception ou modification de l'API publique d'un package publié,exports, fichiers de déclaration, semver ; outils qui importenttypescriptcomme bibliothèque.references/runtimes.md: exécution de.tsdirectement sur Node, Bun ou Deno.references/monorepo.md: workspaces pnpm, Turborepo, packages dépendant les uns des autres.references/jsdoc.md: fichiers.jsvérifiés aveccheckJs, types JSDoc, migration de JavaScript vers TypeScript.