Guide · Concepts · 21 October 2026 · 7 min read

Reading a TypeScript error message

The parts of a tsc error: file, line and column, the TS code, message chains and related locations, and what --pretty and --explainFiles add.

  • Examples checked with TypeScript 5.9

A TypeScript error is more structured than it looks. Each one names a place, a code and a message, and many carry a chain of explanations and a pointer to a second place in your code. Knowing the parts makes the long ones readable, and makes the short ones searchable.

The parts of one error

Here is a file with two mistakes, checked by tsc:

src/cart.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: src/cart.js(11,35): error TS2551: Property 'totalCent' does not exist on type 'Order'. Did you mean 'totalCents'? src/cart.js(13,49): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. src/cart.js(11,35): error TS2551: Property 'totalCent' does not exist on type 'Order'. Did you mean 'totalCents'? src/cart.js(13,49): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. src/cart.js(11,35): error TS2551: Property 'totalCent' does not exist on type 'Order'. Did you mean 'totalCents'? src/cart.js(13,49): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. checked 21 October 2026
/** @typedef {{ sku: string, totalCents: number }} Order */

/** @param {number} cents */
function formatCents(cents) {
  return "$" + (cents / 100).toFixed(2);
}

/** @param {Order} order */
export function receipt(order) {
  const total = formatCents(order.totalCent);error TS2551: Property 'totalCent' does not exist on type 'Order'. Did you mean 'totalCents'?
  return `${order.sku}: ${total} (${formatCents(order.sku)})`;error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
}
Two errors, as tsc reports them.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["src/**/*.js"]
}

When its output is not a terminal (in CI or in a pipe), or with --pretty false, tsc prints each error on one line. This is TypeScript 5.9.3’s output for the file above, with the line numbers as shown on this page:

src/cart.js(10,35): error TS2551: Property 'totalCent' does not exist on type 'Order'. Did you mean 'totalCents'?
src/cart.js(11,49): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Read left to right:

  • src/cart.js(10,35): the file, relative to where tsc ran, then the line and the column, both counted from 1. Editors and CI annotations use exactly these to jump to the spot.
  • error: the category. tsc prints errors; editors also show suggestions (faded unused names, @deprecated strike-throughs) that tsc never prints.
  • TS2551: the code. It identifies the message across versions and languages, and it is what to search for. The error reference has a page for the codes JavaScript projects meet most, with a failing example and the fix.
  • The message, with the names and types filled in. 'Order' is the type as TypeScript names it: your @typedef name when it has one, the written-out shape when it does not.

Codes by range

The number says roughly what kind of problem it is. The ranges come from how TypeScript’s list of messages is organized, and there are exceptions:

CodesMostly aboutExamples
1000sSyntax: the file did not parse as expectedTS1005 ';' expected, TS1109
2000sTypes, names and modules: most errors you will seeTS2322, TS2339, TS2345, TS2307
5000sThe config file and command-line optionsTS5055, TS5101
6000sMessages about files and options, and a few checks such as unused namesTS6133
7000sValues that would be any (the noImplicitAny family)TS7006, TS7016, TS7053
8000sJavaScript files: TypeScript syntax in .js, JSDoc that does not match the codeTS8010, TS8024
17000s, 18000sNewer checks, among them the possibly-null messagesTS18047, TS18048

The pretty output

In a terminal, tsc prints a richer form, and --pretty forces it elsewhere. The same two errors:

src/cart.js:10:35 - error TS2551: Property 'totalCent' does not exist on type 'Order'. Did you mean 'totalCents'?

10   const total = formatCents(order.totalCent);
                                     ~~~~~~~~~

  src/cart.js:1:30
    1 /** @typedef {{ sku: string, totalCents: number }} Order */
                                   ~~~~~~~~~~
    'totalCents' is declared here.

src/cart.js:11:49 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

11   return `${order.sku}: ${total} (${formatCents(order.sku)})`;
                                                   ~~~~~~~~~


Found 2 errors in the same file, starting at: src/cart.js:10

Two things appear only here. The squiggle under the source line shows the exact span, which matters when one line holds several calls. And the indented block under the first error is related information: a second location that explains the first, here the property TypeScript suggested, in your @typedef. Editors show the same thing as a link in the hover. The one-line format leaves it out, which is why CI logs can be harder to read than the editor.

Message chains

When a value does not fit a type because of something deep inside it, tsc reports one error and explains it in steps, each line indented under the one before:

settings.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: settings.js(11,27): error TS2322: Type '{ retries: number; timeoutMs: string; }' is not assignable to type '{ retries: number; timeoutMs: number; }'. Types of property 'timeoutMs' are incompatible. Type 'string' is not assignable to type 'number'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. settings.js(11,27): error TS2322: Type '{ retries: number; timeoutMs: string; }' is not assignable to type '{ retries: number; timeoutMs: number; }'. Types of property 'timeoutMs' are incompatible. Type 'string' is not assignable to type 'number'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. settings.js(11,27): error TS2322: Type '{ retries: number; timeoutMs: string; }' is not assignable to type '{ retries: number; timeoutMs: number; }'. Types of property 'timeoutMs' are incompatible. Type 'string' is not assignable to type 'number'. checked 21 October 2026
/**
 * @typedef {object} Settings
 * @property {{ retries: number, timeoutMs: number }} network
 * @property {"light" | "dark"} theme
 */

const network = { retries: 3, timeoutMs: "5000" };

/** @type {Settings} */
export const settings = { network, theme: "dark" };error TS2322: Type '{ retries: number; timeoutMs: string; }' is not assignable to type '{ retries: number; timeoutMs: number; }'.
  Types of property 'timeoutMs' are incompatible.
    Type 'string' is not assignable to type 'number'.
A nested mismatch: one error, explained line by line.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["**/*.js"]
}
settings.js(10,27): error TS2322: Type '{ retries: number; timeoutMs: string; }' is not assignable to type '{ retries: number; timeoutMs: number; }'.
  Types of property 'timeoutMs' are incompatible.
    Type 'string' is not assignable to type 'number'.

Read a chain from the bottom: the last line is the actual mismatch (a string where a number belongs), and each line above says where it sits. The top line is where TypeScript noticed, which is the network property of the object literal, not the line where timeoutMs was written. When the types in the top line are long, TypeScript shortens them with ...; --noErrorTruncation prints them in full.

Errors about the project, not a line

Some errors have no line: a config option that does not exist, a file that would be overwritten (TS5055), a types entry that cannot be found (TS2688). They print without the (line,col) part, and a few name the config file instead. When the surprise is which files are checked, two options answer it without checking anything else:

npx tsc -p jsconfig.json --listFilesOnly
npx tsc -p jsconfig.json --explainFiles

--listFilesOnly prints every file in the program and stops. --explainFiles (TypeScript 4.2 and later) prints why each one is there: matched by an include pattern, imported by another file, a library for the target, and for JavaScript files whether they are read as ES modules or CommonJS. For the example above, part of it reads:

settings.js
  Matched by include pattern '**/*.js' in 'jsconfig.json'
  File is ECMAScript module because 'package.json' has field "type" with value "module"

In the editor

Editors that run TypeScript’s language service show the same code and message under the squiggle, the related information as a link, and quick fixes when TypeScript has one (“Change spelling to ‘totalCents’”, “Add missing properties”). They also show suggestions that tsc does not report at all. If the editor and npm run lint disagree about an error, they are running different TypeScript versions or different configs; the editor setup pages cover how to make them match.

The examples on this page were checked with TypeScript 5.9, and the output above is what tsc 5.9.3 printed for them.

Questions

Why does the editor show more than npm run lint?

Usually it does not: both run the same checker. The editor shows related locations and quick fixes inline, and tsc prints them only in its pretty output. If the errors themselves differ, the editor is running another TypeScript version or another config; the VS Code page shows how to check.

What does the number in TS2345 mean?

It identifies the message in TypeScript's list of diagnostics; codes stay the same across releases even when wording changes, and in every language tsc can print. Searching for the code finds explanations faster than searching for the text, and this site has a page for the codes JavaScript projects meet most.

How do I see the whole type instead of ...?

Run tsc with --noErrorTruncation. TypeScript shortens long types in messages by default; the option prints them in full, which helps when two long types differ in one property.

Sources

Last reviewed 21 October 2026.