What TypeScript is
Types checked before running, annotations, inference, any vs unknown.
Updated
What TypeScript is
TypeScript (TS) is JavaScript with types. You write types for variables, parameters and results, and a program (the tsc compiler, or your editor) checks before you run the code that you use them correctly.
function total(price: number, qty: number): number {
return price * qty
}
total(10, '2') // ✗ an error in the editor: '2' isn't a number — before runningThe key thing to understand: types disappear at build time. The browser receives plain JavaScript. TS only helps you while you write the code.
| Compile time (while you write) | Runtime (when it runs) | |
|---|---|---|
| Do types exist? | yes — checked by TS | no — erased |
| Who catches mistakes | the editor / tsc |
the user, in production |
Why it's worth it
- You catch mistakes (typos,
undefined, a wrong argument) before running. - Autocomplete — the editor knows what fields an object has.
- Safe refactoring — rename a field and TS shows you every affected place.
- Living documentation — a function's signature says what it takes and what it returns.
The cost: a bit of extra syntax. Next.js, React and every modern library are written in TS.
Type annotations
let name: string = 'Ana'
let age: number = 30
let active: boolean = true
let tags: string[] = ['js', 'ts'] // an array of strings
let point: [number, number] = [10, 20] // a tuple — fixed length and types
function greet(name: string, excited?: boolean): string { // ? = an optional parameter
return excited ? `Hello, ${name}!` : `Hello, ${name}`
}Inference — don't write types everywhere
TS infers the type from the value:
let count = 0 // TS knows: number
const user = { name: 'Ana' } // { name: string }
const doubled = [1, 2].map(n => n * 2) // number[]The practical rule: write types for function parameters and for data coming from outside (APIs, forms). Leave the rest to inference.
The special types — differences and when
| Type | Means | When |
|---|---|---|
any |
"turn off checking" — anything goes | avoid it; it's a hole in the system |
unknown |
"I don't know what this is" — you must check before using it | outside data: JSON.parse, catch (e), APIs |
void |
the function returns nothing useful | handlers, effects |
never |
an impossible value | exhaustive checks (the union types lesson) |
null / undefined |
the absence of a value | with strictNullChecks TS forces you to handle them |
any vs unknown:
const a: any = JSON.parse(text)
a.foo.bar() // TS stays quiet — crashes at runtime
const u: unknown = JSON.parse(text)
u.foo // ✗ TS: check what it is first
if (typeof u === 'object' && u !== null && 'foo' in u) { ... } // ✓Literal types
A type can be an exact value:
let size: 'sm' | 'md' | 'lg' = 'md'
size = 'xl' // ✗ not in the listThat's exactly how the button variants in this app are typed.
Configuration
tsconfig.json controls the checking. The most important option: "strict": true — it turns on all the useful checks (including null/undefined). Next sets it by default.
Summary
- TS = JS + types checked before running; at runtime they disappear.
- Types on parameters and on outside data; the rest — inference.
unknowninstead ofany; alwaysstrict: true.