tsc can type-check JavaScript because it understands JSDoc comments as type annotations. You opt in at one of three levels:
- Per file: put
// @ts-checkon the first line. Other.jsfiles in the project stay unchecked. - Whole project: set
allowJs(include.jsfiles in the program) andcheckJs(report errors in them). Per the docs,checkJsis the same as adding// @ts-checkto every JavaScript file. - Opt out:
// @ts-nocheckskips a file;// @ts-ignoreand// @ts-expect-errorsilence the next line, and the latter errors when the line is no longer wrong (TS2578).
Annotating. @param {string} name, @param {number} [times] for optional, @returns {string}, @type {Foo}, @typedef, @template T for generics, @satisfies, and casts such as /** @type {number} */ (x). Types from another file come in through @import {Pet} from "./types" (TS 5.5) or import("./types").Pet. These tags exist only for the checker; they are not imported at runtime.
Why do it. It adds checking and editor help to a JavaScript codebase without a build step, which fits gradual migration or small scripts. JSDoc types also feed declaration generation: with allowJs, declaration, and emitDeclarationOnly, tsc produced shout(name: string, times?: number): string from the comments below.
Differences from .ts. Unannotated parameters are any unless noImplicitAny is on, and function parameters are optional unless JSDoc says otherwise (Handbook).
Version note (TS 7). The 7.0 announcement says JavaScript support was reworked to match .ts analysis: @enum, @class constructors, a bare ? type, and Closure-style function(string): void are no longer recognised.