TypeScript has become the industry standard for large-scale JavaScript applications. These questions test your ability to use the type system effectively and write maintainable, type-safe code.
Interface: Best for defining object shapes; supports declaration merging (multiple declarations combine); preferred in libraries. Type: More flexible; can represent unions, intersections, primitives, and tuples; cannot be merged. Rule of thumb: Use interfaces for public APIs and object shapes; use types for complex compositions.
Generics let you create reusable components that work with multiple types while maintaining type safety. Think of them as "type variables." Example: function identity<T>(arg: T): T. The T is determined by usage. They're essential for libraries, utility functions, and data structures.
any: Disables all type checking. Use sparingly—it defeats the purpose of TypeScript.
unknown: The type-safe counterpart. You can assign anything to it, but you must narrow the type (with typeof, instanceof, etc.) before using it. Prefer unknown when you genuinely don't know the type.
A union describes a value that can be one of several types: string | number. TypeScript will only allow operations that are valid for all types in the union unless you narrow it first. This is fundamental to TypeScript's control flow analysis.
Pick<T, K>: Creates a type with only the specified keys from T.
Omit<T, K>: Creates a type with all keys except the specified ones.
Partial<T>: Makes all properties optional.
Also useful: Required<T>, Readonly<T>, Record<K, V>. Learn these—they eliminate repetitive type definitions.
Type narrowing refines a broader type to a more specific one using control flow analysis. Techniques: typeof for primitives, instanceof for classes, in for property checks, and custom type guards (function isFish(pet: Fish | Bird): pet is Fish). It's how you safely handle union types.
Enums define named constants. Numeric enums auto-increment (enum Direction { Up, Down }). String enums require explicit values. Modern preference: use as const objects instead (const Direction = { Up: 'UP', Down: 'DOWN' } as const) for better tree-shaking.
Interface: interface Dog extends Animal { breed: string; }
Type: type Dog = Animal & { breed: string; } (intersection)
Interfaces use extends; types use &. Both achieve similar results, but interfaces produce clearer error messages.
never represents values that never occur—functions that always throw, infinite loops, or exhaustive checks. It's useful for ensuring you've handled all cases in a switch statement: if you reach the default case with a never type, TypeScript errors if you missed a case.
Decorators are experimental functions that modify classes, methods, properties, or parameters. Syntax: @decorator. Commonly used in frameworks like Angular and NestJS. They're a stage 3 proposal for JavaScript. Enable with experimentalDecorators in tsconfig.
When strictNullChecks: true, null and undefined are distinct types that can't be assigned to other types without explicit handling. This catches a huge category of bugs. Always enable this in new projects—it's part of strict mode.
Tuples are typed arrays with fixed length and known types per position: [string, number, boolean]. Useful for representing structured data like [x, y] coordinates or [error, result] patterns. Rest elements are allowed: [string, ...number[]].
Mapped types transform properties of an existing type: type Readonly<T> = { readonly [P in keyof T]: T[P] }. They're the foundation of utility types like Partial, Required, and Pick. Master them to create powerful, reusable type transformations.
TypeScript uses "Type Assertion" (value as Type or <Type>value). It tells the compiler "trust me." Unlike casting in other languages, it changes nothing at runtime—it's purely a compile-time hint. Overuse is a code smell.
Ambient declarations describe types for JavaScript libraries. .d.ts files contain only type information, no runtime code. DefinitelyTyped (@types/*) provides these for popular libraries. Write your own for untyped JS modules you can't replace.