Why types
This is JavaScript, the language browsers and Node.js run. add should add two numbers, but line 4 gives it the text "2". JavaScript runs it anyway: + joins text, so it prints 23, not 5. No warning.
TypeScript is JavaScript plus types. A type says what kind of value something is: number for numbers, string for text. Writing a: number and b: number says add only takes numbers.
The check
TypeScript is not run as it is. First the TypeScript compiler, a program called tsc, reads the whole file and checks every value against its type. Nothing has run yet.
"2" is a string, but add wants a number, so tsc reports an error on line 4: Argument of type 'string' is not assignable to parameter of type 'number'. The bug is found before anything runs.
You change "2" to the number 2 and run tsc again. Now every value matches its type, so the check passes with no errors.
Plain JavaScript out
tsc then writes add.js: the same code with the types removed, so a: number becomes just a. Browsers and Node.js only understand JavaScript, so this is the file that runs.
Compare line 1 of both files: add.js has no types at all. Types exist only for the check. While the program runs nothing checks them, which is why the check comes first.
Node.js or a browser runs add.js. add(2, 3) gives 5 and console.log prints it. The program is the same JavaScript as before, but the bug was stopped before it ever ran.
In your editor
Editors such as VS Code run the same checker as you type. They underline mistakes at once, and because add has types they can show what it needs, add(a: number, b: number): number, and suggest names to finish your code.
What happens
;; step 1/9 · js-bug
add.js (plain JavaScript)
1 function add(a, b) {
2 return a + b;
3 }
> 4 console.log(add("2", 3));
"2" is text (a string), 3 is a number
"2" + 3 → "23" + joins text
node add.js prints 23
By default tsc still writes the .js file even when it finds type errors; turn on the noEmitOnError setting to stop that. Either way, you see the error first. The add.js shown is exactly what tsc 5.9 writes for this file with no settings. Other settings (such as the target version of JavaScript, or strict mode adding "use strict";) can change small details.