TypeScript Basics
EasyTypeScript adds a compile-time type system on top of JavaScript. Every valid JavaScript file is already valid TypeScript, but TypeScript lets you annotate variables, parameters, and return values so the compiler catches errors before your code ever runs. Understanding the primitive types, type annotations, and basic inference rules is the foundation for everything else in TypeScript.
Interactive Visualization
Key Points
- TypeScript is a strict superset of JavaScript — all JS is valid TS
- Type annotations use a colon syntax: `let name: string`
- Primitive types include string, number, boolean, null, undefined, symbol, and bigint
- TypeScript infers types when you assign a value, so explicit annotations are often optional
- The `unknown` type is the type-safe counterpart of `any` — it requires narrowing before use
- Union types (`string | number`) allow a value to be one of several types
- Literal types (`"hello"` or `42`) restrict values to exact literals
Code Examples
Type Annotations & Inference
// Explicit annotations let name: string = 'Alice' let age: number = 30 let active: boolean = true // TypeScript infers these types automatically let city = 'London' // inferred as string let score = 100 // inferred as number let items = [1, 2, 3] // inferred as number[] // Function with typed parameters and return function greet(name: string, formal: boolean): string { return formal ? `Dear ${name}` : `Hi ${name}` }
TypeScript can infer types from initial assignments, but explicit annotations on function parameters are required when the compiler cannot infer them from context.
Union & Literal Types
// Union type — accepts multiple types type ID = string | number function findUser(id: ID): void { if (typeof id === 'string') { console.log(id.toUpperCase()) // TS knows id is string here } else { console.log(id.toFixed(2)) // TS knows id is number here } } // Literal type — restricts to exact values type Direction = 'north' | 'south' | 'east' | 'west' function move(dir: Direction): void { // dir can only be one of the four strings } move('north') // OK // move('up') // Error: not assignable to Direction
Union types combine multiple types, while literal types restrict a value to specific constants. Together they model finite sets of valid values.
Interfaces vs Type Aliases
// Interface — describes object shapes, can be extended interface User { name: string age: number } interface Admin extends User { role: 'admin' } // Type alias — can represent any type, including unions type Result = { success: true; data: string } | { success: false; error: string } // Intersection type — combine multiple types type AdminUser = User & { role: 'admin'; permissions: string[] }
Interfaces define object contracts and support declaration merging. Type aliases are more flexible — they can represent unions, intersections, and mapped types.
Common Mistakes
- Using `any` to silence type errors instead of properly typing the value
- Confusing `unknown` with `any` — unknown requires narrowing, any bypasses all checks
- Forgetting that TypeScript types are erased at runtime — they provide no runtime safety
- Over-annotating when TypeScript can infer the type automatically
- Using `String` (capital S object wrapper) instead of `string` (primitive type)
Interview Tips
- Explain the difference between `any` and `unknown` — this is a classic question
- Know when to use `interface` vs `type` — interfaces for object shapes, types for unions and complex compositions
- Mention that TypeScript is structurally typed, not nominally typed
- Be ready to explain type inference and when explicit annotations are needed