TypeScript Guide: Types and Best Practices
·8 min read
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