3. TypeScript
TypeScript Fundamentals
3.1.1 Basic Types
TypeScript’s primitive types form the building blocks of any application. The language provides string, number, boolean, null, undefined, symbol, and bigint. These types can be combined to create more complex structures.
- Arrays: Defined with
string[]or the genericArray<string>syntax. - Tuples: Fixed‑length arrays where each position has a known type, e.g.
[string, number]. - Enums: Allow defining a set of named constants. Numeric enums start at 0 by default, while string enums require explicit initialization.
- Any and Unknown:
anydisables type checking, whereasunknownrequires narrowing before use.
Example:
const age: number = 25;
const tags: string[] = ['react', 'nextjs'];
const user: [string, number] = ['Alice', 30];
3.1.2 Interfaces
Interfaces describe the shape of objects. They are extensible and support declaration merging, meaning multiple declarations with the same name are automatically combined.
- Basic syntax:
interface User { name: string; } - Extension:
interface Admin extends User { permissions: string[]; } - Optional properties: Marked with
?(e.g.,error?: string). - Readonly: Prefixed with
readonlyto prevent reassignment. - Generics in interfaces:
interface ApiResponse<T> { data: T; status: number; error?: string; }
Example:
interface ApiResponse<T> {
data: T;
status: number;
error?: string;
}
3.1.3 Type Aliases
Type aliases create a name for any type, including unions, intersections, and tuples. Unlike interfaces, they cannot be extended with extends; instead, intersections (&) are used.
- Union alias:
type ID = string | number; - Object alias:
type User = { name: string; age: number; } - Discriminated union:
type Result<T, E> = { success: true; data: T } | { success: false; error: E };
3.1.4 Enums
Enums can be numeric (default) or string‑based. Const enums (const enum) inline their values at compile time, eliminating runtime overhead.
- Numeric enum:
enum Status { Pending = 0, Success = 1, Error = 2 } - String enum:
enum Direction { Up = "UP", Down = "DOWN" } - Const enum:
const enum LogLevel { Off, Error, Warn, Info, Debug }
Usage example:
function handle(status: Status) {
if (status
Advanced TypeScript Features
Generics
Generics allow you to write reusable, type-safe code. They work like parameters for types:
function identity<T>(arg: T): T {
return arg;
}
const num = identity<number>(42);
const str = identity<string>("hello");
Discriminated Unions
Use a common literal property to create safe type narrowing:
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rectangle"; width: number; height: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "rectangle": return s.width * s.height;
}
}
Utility Types
TypeScript provides built-in utility types for common transformations:
Pick<T, K>- Select specific propertiesOmit<T, K>- Remove specific propertiesPartial<T>- Make all properties optionalRequired<T>- Make all properties requiredRecord<K, V>- Create object type with keys K and values V
Type Guards
Type guards help narrow types at runtime:
function isString(val: unknown): val is string {
return typeof val === "string";
}
TypeScript with React
In React, TypeScript enhances component development with typed props, state, and hooks. This catches errors early and provides excellent IDE support for autocomplete and refactoring.
TypeScript Configuration
The tsconfig.json file configures the TypeScript compiler. Key options include strict mode for maximum type safety, target for output JavaScript version, and module for module system. Enabling noImplicitAny and strictNullChecks catches common errors early in development.
TypeScript in Popular Frameworks
Modern frameworks have first-class TypeScript support. Next.js, Angular, and Vue 3 all provide excellent TypeScript integration. Using TypeScript with these frameworks improves developer experience through better autocompletion, type checking, and refactoring capabilities.
Migration from JavaScript to TypeScript
Adopting TypeScript incrementally is recommended. Start by renaming .js files to .ts and fixing type errors gradually. Use the any type temporarily for untyped code, then progressively replace it with proper types. This approach allows teams to benefit from TypeScript without disrupting ongoing development.