TypeScript checking can start without changing a JavaScript build
The team's migration guide separates checking from emission. JavaScript sources can gain diagnostics through configuration and declaration packages before any syntax conversion.
Adopting static checking does not require replacing the process that produces a JavaScript application. TypeScript can analyze existing JavaScript and report diagnostics without emitting another copy. That separation makes adoption a question of improving the model of the code before it becomes a question of changing the code's language.
Nathan Shively-Sanders's June 14 migration guide starts from that arrangement. It keeps JavaScript source and the existing build, while adding a TypeScript configuration and declarations. The compiler supplies errors at the command line and information for supported editors.
The guide uses TypeScript-eslint-parser as its worked example. The configuration commit it links adds a checking configuration without converting the source files. That concrete boundary matters because a build migration can otherwise become a prerequisite for obtaining any useful diagnostics.
I find this approach consistent with the part of TypeScript I value most. Its tooling can improve the understanding of a web codebase without requiring a single large conversion. The useful question is which relationships the checker can already model and where it still lacks information.
Checking and emission have separate controls
The guide combines allowJs, checkJs and noEmit. Allowing JavaScript makes those files part of the compiler's input. Checking JavaScript requests diagnostics for them. Disabling emission keeps the compiler from becoming another producer of runtime output.
A configuration based on the guide looks like this.
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"target": "esnext",
"module": "commonjs",
"resolveJsonModule": true,
"strict": false
},
"exclude": [
"tests/fixtures/",
"tests/integration/"
]
}
The module setting matches the guide's Node-oriented example. It is not a claim that every browser project should use CommonJS. The important architectural choice is noEmit, which lets analysis run beside the existing production of JavaScript.
The guide notes that target and module choices can still influence diagnostics even without output. It specifically mentions errors involving classes such as Map and Set. A configuration describes the environment the checker assumes, so suppressing output does not make every other option irrelevant.
ResolveJsonModule lets the compiler analyze JSON modules used by the project. The guide makes it optional for projects that do not require such files. That is another example of modeling actual inputs instead of selecting options merely because they appear in a sample.
The checked file set needs to reflect the project
The parser's test fixtures include intentionally malformed JavaScript. Asking a compiler to treat those fixtures as ordinary program source creates errors unrelated to the implementation being checked. The guide excludes fixture and integration directories for that reason.
This is an important scope distinction. A file can be essential to testing without being source that should satisfy the language rules. The exclusion does not claim the tests are unimportant. It identifies their different role as data consumed by the parser.
The guide also describes include for selecting a subset of source and files for an explicit list. Those choices provide different ways to state the checking boundary. A small experiment can begin with a selected part of the codebase without treating everything in the repository as one coherent program.
A correctly scoped first run should produce diagnostics in both the command line and editor. Agreement matters because an author needs to understand which project configuration the editor is using. A command that finds errors and an editor that appears clean may be analyzing different inputs or assumptions.
Declarations supply a model of dependencies
The next step in the guide is installing declaration packages for dependencies. JavaScript libraries can have interfaces described through packages in the @types namespace. Those declarations give the checker information it cannot obtain merely from the name of a dependency.
For the example parser, the guide lists Node and Jest declarations among its starting dependencies. It also discusses packages for the syntax tree and supporting libraries. These are development inputs to analysis, separate from rewriting the library's runtime implementation.
A missing declaration and a real call error can initially look similar to the developer encountering a diagnostic. The compiler may lack the dependency's model, or it may have enough information to show that the call is invalid. Adoption requires distinguishing those cases before treating every error as an application defect.
The guide also reports declarations that are incomplete or imported incorrectly in its example. Installing a package is therefore not proof that the compiler now understands every value. The correspondence between actual library behavior and its declaration remains part of the work.
JSDoc preserves ordinary JavaScript source
The guide uses JSDoc to add information without introducing TypeScript-only syntax into JavaScript files. This keeps the source executable by the same existing process. The tradeoff is a less direct notation for some type information than ordinary TypeScript annotations.
A declaration file can hold miscellaneous types that do not fit conveniently in those comments. That keeps the checker model separate from runtime statements. The goal of this stage is useful analysis, so converting the file extension is not required to make progress.
I prefer this explicit separation of adoption steps. Improving dependency declarations and selecting a coherent file set can provide immediate editor value. Changing the build can then be considered on its own merits, with evidence about the checking the project actually receives.
The guide's first stage therefore ends with an analyzable JavaScript project, even if many diagnostics still need interpretation. Its configuration establishes input scope and prevents emission. Declaration packages and comments gradually improve the model without requiring the application to change how its JavaScript is produced.