First Steps with TypeScript
TypeScript is a typed superset of JavaScript: any valid JavaScript code is (almost always) valid TypeScript, to which you add type annotations. The compiler checks those types before execution, then erases them: the browser or Node.js only runs JavaScript.
function prixTTC(ht: number, taux: number): number {
return ht * (1 + taux);
}
prixTTC(100, 0.2); // 120
prixTTC("100", 0.2); // Compile error: string is not assignable to number
In JavaScript, the second line would silently produce "1000.2"… or a NaN further down the line. TypeScript turns that bug into an error visible in the editor.
Installing and compiling
npm install --save-dev typescript # TypeScript 7
npx tsc --init # creates tsconfig.json (strict, module nodenext, target esnext)
npx tsc # checks and compiles .ts files into .js
npx tsc --noEmit # checks only, without producing files
TypeScript 7 is the compiler rewritten in Go: same typing rules and same tsc command, but much faster checking. Keep "strict": true in tsconfig.json (it is also the default since TypeScript 6). Strict mode enables, among other things, noImplicitAny (a parameter without a type is an error) and strictNullChecks (null and undefined are not assignable to just any type).
In an older configuration, tsc now rejects removed options ("target": "ES5", "moduleResolution": "node", baseUrl, outFile): remove them. Node.js types are no longer loaded automatically: install @types/node and add "types": ["node"].
Vite and Node.js 26 (node app.ts) run TypeScript by stripping the types without checking them; Node also rejects syntax that produces code, such as enum. tsc --noEmit remains the checking tool.
Basic types
let nom: string = "Ada";
let age: number = 36; // integers and decimals: a single number type
let actif: boolean = true;
let notes: number[] = [12, 15.5];
let point: [number, number] = [48.85, 2.35]; // tuple: fixed length and types
let rien: null = null;
let pasEncore: undefined = undefined;
Inference: don’t annotate everything
TypeScript deduces the type of an initialized variable:
let ville = "Lyon"; // inferred: string
ville = 69; // Error: number is not assignable to string
const tva = 0.2; // inferred: the literal type 0.2 (a constant doesn't change)
const totaux = [10, 20].map((n) => n * 2); // inferred: number[]
Rule of thumb: annotate function parameters and exported values; let inference do the work for local variables.
any and unknown
any turns off all checking: avoid it, it is an escape hatch. unknown means “I don’t know yet” and forces you to check before using the value:
function longueur(x: unknown): number {
if (typeof x === "string") return x.length; // here x is a string
return 0;
}
null and undefined in strict mode
function initiale(nom: string | undefined): string {
// nom.charAt(0) would be rejected: nom may be undefined
return nom ? nom.charAt(0) : "?";
}
The type string | undefined is a union (covered in detail later). The compiler forces you to handle the missing case, which eliminates a large share of “Cannot read properties of undefined” errors.
Key takeaways
- Types are checked at compile time and erased at runtime.
- Annotate function inputs and let inference do the rest.
- Prefer
unknowntoany, and keep strict mode on.
Exercises
Solutions and tests stay on the server. In the student space, your code is run and checked, and the tutor gives hints before the solution.
Annotate a price function
Add type annotations to
prixTTC:htis a number,tauxis an optional number with a default of 0.2, and the function returns a number rounded to 2 decimals.The tests check the result and that a call with a string is rejected by the compiler.
function prixTTC(ht, taux) { return Math.round(ht * (1 + taux) * 100) / 100; }Return a tuple or null
Write
minMax(valeurs: number[])which returns the tuple[min, max], ornullif the array is empty. Annotate the return type precisely.function minMax(valeurs: number[]) /* : type de retour ? */ { // TODO }any or unknown?
A function receives a piece of data whose type you don’t know (for example the result of
JSON.parse). Which type should you declare so the compiler forces you to check it before use?- any
- unknown
- object
- never
End-of-lesson quiz
What happens to a type annotation at runtime?
- It is checked by the browser
- It is erased: only the JavaScript is executed
- It is converted into an automatic test
What is the inferred type of
const taux = 0.2?- number
- The literal type 0.2
- any
What does the strictNullChecks option do?
- Forbids using null
- Prevents assigning null or undefined to a type that doesn't include them
- Replaces null with undefined
The rest of the course
- Objects, Interfaces, Unions and Narrowing18 min
- Typed Functions and Generics18 min
- Discriminated Unions and Utility Types18 min
- Typing the DOM and API Data20 min