TypeScript is JavaScript with an optional type system layered on top — every valid JS file is already close to valid TypeScript. The value comes from catching a category of bugs at compile time instead of at runtime, in production.
let age: number = 30
let name: string = 'Amara'
let isActive: boolean = true
let tags: string[] = ['dev', 'admin']
Most of the time, though, you don't even write these — TypeScript infers them from the initial value, so let age = 30 is already typed as number without the annotation.
function greet(name: string): string {
return `Hello, ${name}`
}
If you call greet(42), TypeScript flags it before you ever run the code — a whole class of "undefined is not a function" bugs simply can't happen for typed parameters.
interface User {
id: number
name: string
email?: string
}
function printUser(user: User) {
console.log(user.name)
}
The ? marks email as optional. Any object passed to printUser must have id and name of the right types, or TypeScript won't compile it.
function formatId(id: number | string): string {
return `#${id}`
}
Union types describe values that can legitimately be more than one type — common for IDs that might come from different sources, or for a status field with a fixed set of allowed strings.
function firstItem<T>(list: T[]): T {
return list[0]
}
firstItem<number>([1, 2, 3]) // returns number
firstItem<string>(['a', 'b']) // returns string
Generics let a function stay type-safe without hardcoding a specific type — the caller's input determines T, and the return type follows automatically.
strict: false if migrating an existing project. Enabling strict mode on day one against a large legacy codebase produces hundreds of errors at once. Turn it on incrementally, file by file, instead.
Comments