Chapter 2
Your First Type Error
What tsc is actually for.
The error you fixed in chapter 1 was a typo. consol isn’t a word TypeScript
knows, so it said so. That’s a useful skill, but it’s not really what
TypeScript is for. Plenty of languages catch a misspelled name. What sets
TypeScript apart is the thing this chapter is about: it keeps track of what
kind of value is sitting inside a name, and it stops you the moment you
contradict yourself.
Giving a value a name
let score = 7;
let gives a value a name you can reuse. There’s a lot more to say about it,
const in particular, and it’s all coming next chapter. For now, one line is
enough: score now stands in for 7 everywhere you use it, the same way
name stood in for a string back in chapter 1.
let score = 7;
console.log(score);
7
Nothing new so far. Here’s the part that is.
TypeScript remembers what you gave it
You never wrote the word number anywhere in that line. TypeScript looked at
7, decided score is a number, and it’s not going to forget that decision
just because you didn’t write it down yourself.
Try changing what’s inside score:
let score = 7;
score = "seven";
console.log(score);
npx tsc score.ts
score.ts(2,1): error TS2322: Type 'string' is not assignable to type 'number'.
Same shape as chapter 1’s message: a file, a line, a column, and now a code
that starts with TS instead of the message speaking for itself. TS2322 is
just an ID, TypeScript has a few thousand of these, and you’ll get a feel for
the common ones without ever memorising a list. What matters is the sentence
after it. score was a number. You handed it a string. TypeScript noticed.
What JavaScript would have let you do
Here’s the sales pitch, and it’s worth seeing directly rather than taking on
faith. Open score.js, the file tsc produced:
"use strict";
let score = 7;
score = "seven";
console.log(score);
Run it anyway:
node score.js
seven
It works. JavaScript has no objection to a variable holding a number one
moment and a string the next, it just quietly goes along with whatever you
last put there. That’s not a defect in JavaScript, it was designed to be
forgiving. It’s also exactly how a score variable ends up holding text
somewhere deep in a program, and three functions later something tries to do
arithmetic on it and gets nonsense instead of an error.
TypeScript’s whole job is catching that before it becomes JavaScript’s problem. The check happens once, while you’re sitting right there looking at the file. The alternative is finding out at 2am, from a bug report, three weeks after you wrote the line, in a function nowhere near the one that actually put the string there in the first place. By then the type is long gone and all you have left is a symptom.
That’s the trade this whole book keeps making, and the reason the two-command
loop from chapter 1 exists at all. Plain JavaScript would let you skip
straight to node score.js and never know anything was wrong until it broke
in some less convenient way, later, somewhere else.
TypeScript doesn’t stop at the first mistake
One more difference worth knowing before the project. In C++, one broken line can make the rest of the file unreadable to the compiler, so you fix the first error and recompile, because the others might not even be real yet. TypeScript’s checker doesn’t work that way. It checks the whole file and tells you everything it found, independent mistakes and all, in one pass:
let score = 7;
let ready = true;
score = "seven";
ready = "yes";
mixed.ts(3,1): error TS2322: Type 'string' is not assignable to type 'number'.
mixed.ts(4,1): error TS2322: Type 'string' is not assignable to type 'boolean'.
Two real, unrelated mistakes, two messages, both trustworthy. Read from the top, fix what you see, and don’t assume a later message will vanish the way it might in C++. It usually won’t, because it was never dependent on the one above it.
Exercise 1 · Two kinds of red
Write a small file with one line like chapter 1’s typo (a misspelled name)
and one line like this chapter’s mistake (a value that changes type).
Compile it once and look at both messages side by side. One starts with
TS2552, one with TS2322. You don’t need to remember the numbers, just
notice that they’re not the same complaint wearing different words.
How to look one up
You’ll be searching for these for as long as you write TypeScript, and the
code in front of the message makes that easier than it looks. Search
TS2322 on its own and you’ll land on pages explaining exactly this error,
written by people who hit it before you did. That’s one advantage a numbered
code has over free text: two people on opposite sides of the world with
completely different variable names still typed the same four characters
into the same search box.
The message after the code is still worth reading first, though. Most of the time it already tells you everything: which type you have, which type was expected, and often a suggestion sitting right there in the sentence. The search is for when the message alone doesn’t make it click.
A field guide, two entries so far
| Code | What it means | You saw it in |
|---|---|---|
TS2552 | You referred to a name that doesn’t exist, usually a typo | Chapter 1 |
TS2322 | A value doesn’t match the type its variable already has | This chapter |
Check yourself
Project
Fix the profile card
Roughly 20 minutes
Type this out exactly as written, mistakes included, and save it as
card.ts:
let studentName = "Ada Lovelace";
let age = 36;
let isMember = true;
console.log(studenName + " is " + age + " years old.");
age = "thirty-six";
isMember = "yes";
console.log("Member:" +isMember);Compile it:
npx tsc card.tsYou should see three messages. One is a name you’ve met before, the other two are new this chapter. Fix all three, in any order, they don’t depend on each other, and compile again until the output is silent.
Then run it:
node card.jsIt runs, and something about the last line still looks wrong. That’s not a
type error, and no version of tsc will ever flag it for you, it’s a plain
old spacing mistake in how the pieces got joined together. Find it and fix
it by eye.
This is worth sitting with for a second: a file with zero type errors is not the same thing as a file that’s right. TypeScript checks what it can check. The rest is still on you.