·8 min read
TypeScript Guide: Types and Best Practices
TypeScript adds static typing to JavaScript. It catches bugs at compile time, improves IDE support, and makes large codebases maintainable.
Basic Types
let name: string = "Alice"; let age: number = 30; let active: boolean = true; let items: string[] = ["a", "b"]; let data: [string, number] = ["Alice", 30]; // tuple let value: any = "anything"; let nothing: void = undefined; let never: never; // never returns
Interfaces
interface User {
id: number;
name: string;
email: string;
age?: number; // optional
readonly createdAt: Date; // readonly
}
interface Admin extends User {
role: "admin" | "superadmin";
permissions: string[];
}Type Aliases
type ID = string | number;
type Status = "active" | "inactive" | "banned";
type Point = { x: number; y: number };
type Callback = (data: string) => void;Generics
function identity<T>(value: T): T {
return value;
}
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
type UserResponse = ApiResponse<User>;
type ListResponse = ApiResponse<User[]>;Utility Types
// Partial - all properties optional type PartialUser = Partial<User>; // Required - all properties required type RequiredUser = Required<User>; // Pick - select specific properties type UserName = Pick<User, "name" | "email">; // Omit - exclude properties type UserWithoutId = Omit<User, "id">; // Record - map keys to values type Roles = Record<string, string[]>; // Exclude / Extract type StringOrNumber = string | number | boolean; type OnlyString = Exclude<StringOrNumber, number>; // string | boolean
Functions
function add(a: number, b: number): number {
return a + b;
}
const greet = (name: string): string => {
return `Hello, ${name}`;
};
// Function overloads
function format(value: string): string;
function format(value: number): string;
function format(value: string | number): string {
return String(value);
}Classes
class Animal {
constructor(
public name: string,
private age: number,
protected species: string
) {}
greet(): string {
return `I am ${this.name}`;
}
}Type Guards
function isString(value: unknown): value is string {
return typeof value === "string";
}
function process(value: string | number) {
if (isString(value)) {
console.log(value.toUpperCase()); // TS knows it's string
} else {
console.log(value.toFixed(2)); // TS knows it's number
}
}Best Practices
- Prefer interfaces for object shapes, types for unions/intersections
- Use
unknowninstead ofany - Enable strict mode in tsconfig.json
- Use const assertions for literal types:
as const - Prefer readonly arrays and properties when data should not mutate