Warm-up · Activity 1 of 7
// B1.1 · ~30 min · Beginner
Why static types: catching mistakes before the program runs
After this lesson you can say what tsc checks before a program runs, add type annotations where they are needed, and use a diagnostic such as error TS2322 to fix the line it names.
Lesson 1 of 5 in B1 Setup and the basics
You will be able to
- Explain what tsc checks before a program runs, and why node main.ts alone checks no types
- Annotate variables and parameters, and leave annotations out where TypeScript infers the type
- Read a tsc diagnostic: the file, line and column, the TS code and the message
Predict · Activity 2 of 7
Predict before you read on: you run npx tsc on this main.ts. What does it report?
function double(n: number) { return n * 2; } console.log(double("21"));Practice · Activity 3 of 7
Fill in the type of width, so that tsc accepts the function and it prints 12.
function area(width: ____, height: number): number { return width * height; } console.log(area(3, 4));function area(width: , height: number): number {Practice · Activity 4 of 7
Nothing here is annotated. What does tsc report?
let price = 4.5; price = "free";Practice · Activity 5 of 7
tsc prints main.ts(5,20): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. Match each part to what it tells you.
Brain teaser · Activity 6 of 7
Brain teaser. tsc rejects this file, but you skip tsc and run node main.ts. What does it print?
const count: number = "3"; console.log(count + 1);Apply · Activity 7 of 7
Mini-task. Write a function formatPrice that takes an amount and a currency and returns text such as 4.50 EUR (amount.toFixed(2) gives the two decimals). Annotate both parameters and the return type, then call it once with console.log. Check it with the editor, or run npx tsc and node main.ts if you have TypeScript installed. Then pass "4.5" instead of 4.5 and read the error.
Check your work against this list
Build it yourself
Read the worked example, then write the exercises. Your code runs in your browser or on your computer and is never uploaded.
Worked example
A checked shopping total
This program adds up three prices and adds 19% tax. The array and the function parameters are annotated; total is not, because TypeScript infers number from its first value. Run npx tsc: it prints nothing, which means no errors. Then run node main.ts. Try passing "0.19" as the rate and run tsc again. The next lesson installs TypeScript 7.0; the editor on this page checks with TypeScript 6.0, which reports the same errors for every program in this lesson.
main.ts
// A shopping total. tsc checks every use of these values before node runs them.
const prices: number[] = [3.5, 4.25, 2];
let total = 0; // no annotation: TypeScript infers number
function addTax(amount: number, rate: number): number {
return amount * (1 + rate);
}
for (const price of prices) {
total += price;
}
console.log("items:", prices.length);
console.log("total:", total);
console.log("with 19% tax:", addTax(total, 0.19).toFixed(2));
Run it with
npx tsc
node main.tsOutput
items: 3
total: 9.75
with 19% tax: 11.60- number[] means an array of numbers; pushing text into prices would be a type error.
- total has no annotation, yet TypeScript treats it as a number everywhere below.
- The annotations are gone when Node.js runs the file: the output is what the same JavaScript would print.
- toFixed(2) returns text with two decimals, which is why the last line shows 11.60.
Change it and run it
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the TypeScript compiler (up to 2.1 MB) and keeps it cached. Your code stays on your device.
Exercises
Exercise 1 of 2
Annotate the parameters
This function works in JavaScript, but tsc rejects it: Parameter 'width' implicitly has an 'any' type, and the same for height. Annotate both parameters as numbers, and the return type too. Run the tests: the first one is the type-check.
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the TypeScript compiler (up to 2.1 MB) and keeps it cached. Your code stays on your device.
Hints
Hint 1
An annotation goes after the name, with a colon: width: number.
Hint 2
The return type goes after the closing bracket of the parameter list: (…): number {
Hint 3
The finished first line is export function area(width: number, height: number): number {
Show a solution
One way to solve it. Yours can look different and still pass the checks.
export function area(width: number, height: number): number {
return width * height;
}
Run it on your computer
Install TypeScript 7.0 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.
main.ts
export function area(width, height) {
return width * height;
}
main.test.ts
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {area} from './main.ts';
test('area(3, 4) is 12', () => {
assert.equal(area(3, 4), 12, 'area(3, 4) should be 12');
});
test('area(2.5, 2) is 5', () => {
assert.equal(area(2.5, 2), 5, 'area(2.5, 2) should be 5');
});
package.json
{
"type": "module"
}
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"lib": [
"esnext",
"dom"
],
"types": [],
"strict": true,
"noEmit": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true,
"allowImportingTsExtensions": true
},
"include": [
"**/*.ts"
],
"exclude": [
"**/*.test.ts"
]
}
npx tsc needs TypeScript in the folder: run npm install --save-dev typescript there once. tsc checks the types; Node.js runs main.ts by removing them.
Run the program:
npx tsc
node main.tsRun the checks (needs learnrun.js in the same folder):
npx tsc
node --testDownload learnrun.jsExercise 2 of 2
Fix what tsc reports
This program should print Points: 42, but it prints Points: 402, and tsc reports two errors. Run the tests or npx tsc, go to each line and column the diagnostics name, and fix the values there. Leave the function as it is: it is correct.
Tab indents and Shift+Tab outdents. To leave the editor with the keyboard, press Esc, then Tab.
The first run downloads the TypeScript compiler (up to 2.1 MB) and keeps it cached. Your code stays on your device.
Hints
Hint 1
The first diagnostic is main.ts(6,7): error TS2322. Line 6 stores text in a variable annotated as number.
Hint 2
The second, on line 7, is about saved: TypeScript inferred string from "40".
Hint 3
Remove the quotes: numbers are written without them, as 40 and 2.
Show a solution
One way to solve it. Yours can look different and still pass the checks.
export function addPoints(a: number, b: number): number {
return a + b;
}
const saved = 40;
const bonus: number = 2;
console.log("Points:", addPoints(saved, bonus));
Run it on your computer
Install TypeScript 7.0 or newer. Save these files in one folder, open a terminal in that folder, and run the commands below.
main.ts
export function addPoints(a: number, b: number): number {
return a + b;
}
const saved = "40";
const bonus: number = "2";
console.log("Points:", addPoints(saved, bonus));
main.test.ts
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';
import {addPoints} from './main.ts';
test('addPoints(40, 2) is 42', () => {
assert.equal(addPoints(40, 2), 42, 'addPoints(40, 2) should be 42');
});
test('the program prints Points: 42', async () => {
const out = (await runMain()).trimEnd();
assert.equal(out, 'Points: 42', `the program printed ${JSON.stringify(out)}`);
});
package.json
{
"type": "module"
}
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"lib": [
"esnext",
"dom"
],
"types": [],
"strict": true,
"noEmit": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true,
"allowImportingTsExtensions": true
},
"include": [
"**/*.ts"
],
"exclude": [
"**/*.test.ts"
]
}
npx tsc needs TypeScript in the folder: run npm install --save-dev typescript there once. tsc checks the types; Node.js runs main.ts by removing them.
Run the program:
npx tsc
node main.tsRun the checks (needs learnrun.js in the same folder):
npx tsc
node --testDownload learnrun.jsCommon mistakes
Text in a variable annotated as a number
let count: number = 0;
count = "1";
console.log(count);
What tsc or Node.js prints
main.ts(2,1): error TS2322: Type 'string' is not assignable to type 'number'.Why, and the fix
count is a number, so it can only ever hold numbers. "1" in quotes is text. Line 2, column 1 is where the text is assigned. Write count = 1 without quotes. If you really need to turn text into a number, convert it with Number("1").
A parameter without a type
function greet(name) {
return "Hello, " + name;
}
console.log(greet("Ada"));
What tsc or Node.js prints
main.ts(1,16): error TS7006: Parameter 'name' implicitly has an 'any' type.Why, and the fix
With strict on, TypeScript does not guess what a parameter holds, and it will not silently turn it into any, which would switch checking off for it. Say what you expect: function greet(name: string). The call greet("Ada") then gets checked too.
A typo in a method name
let city = "Berlin";
console.log(city.toUppercase());
What tsc or Node.js prints
main.ts(2,18): error TS2551: Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?Why, and the fix
Names are case-sensitive, and TypeScript knows every method a string has. It reports the typo before the program runs and suggests the right name. Without tsc, node main.ts stops only when it reaches the line, with TypeError: city.toUppercase is not a function. Write toUpperCase.
TypeScript in the browser: the TypeScript 6.0.3 compiler, Apache-2.0, then your browser’s own engine. Licence and source
Exit ticket
5 questions, no hints. Score 80% or more to complete the lesson.
Finish every activity above to unlock the exit ticket.