// 1. Basic types
let username: string = 'Alex';
let age: number = 30;
let isActive: boolean = true;
let items: string[] = ['item1', 'item2'];
let numbers: Array<number> = [1, 2, 3];
let tuple: [string, number] = ['Alex', 30];
// 2. Interfaces
interface User {
id: number;
username: string;
email: string;
age?: number; // Optional property
readonly createdAt: Date; // Read-only property
}
const user: User = {
id: 1,
username: 'alex',
email: 'alex@example.com',
createdAt: new Date(),
};
// user.id = 2; // OK
// user.createdAt = new Date(); // Error: readonly
// 3. Type aliases
type ID = string | number;
type Status = 'pending' | 'active' | 'inactive';
interface Product {
id: ID;
name: string;
status: Status;
price: number;
}
// 4. Functions
function greet(name: string): string {
return `Hello, ${name}!`;
}
const add = (a: number, b: number): number => a + b;
// Optional parameters
function buildName(firstName: string, lastName?: string): string {
return lastName ? `${firstName} ${lastName}` : firstName;
}
// Default parameters
function multiply(a: number, b: number = 1): number {
return a * b;
}
// Rest parameters
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
// Function type
type MathOperation = (a: number, b: number) => number;
const subtract: MathOperation = (a, b) => a - b;
// 5. Generics
function identity<T>(arg: T): T {
return arg;
}
const numIdentity = identity<number>(42);
const strIdentity = identity<string>('hello');
// Generic interface
interface Response<T> {
data: T;
status: number;
message: string;
}
interface UserData {
id: number;
name: string;
}
const response: Response<UserData> = {
data: { id: 1, name: 'Alex' },
status: 200,
message: 'Success',
};
// Generic constraints
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(arg: T): void {
console.log(arg.length);
}
logLength('hello'); // OK
logLength([1, 2, 3]); // OK
// logLength(42); // Error: number doesn't have length
// 6. Union and intersection types
type StringOrNumber = string | number;
function formatValue(value: StringOrNumber): string {
if (typeof value === 'string') {
return value.toUpperCase();
}
return value.toFixed(2);
}
// Intersection type
interface Nameable {
name: string;
}
interface Ageable {
age: number;
}
type Person = Nameable & Ageable;
const person: Person = {
name: 'Alex',
age: 30,
};
// 7. Enums
enum UserRole {
Admin = 'ADMIN',
User = 'USER',
Guest = 'GUEST',
}
interface AuthUser {
username: string;
role: UserRole;
}
const admin: AuthUser = {
username: 'admin',
role: UserRole.Admin,
};
// Numeric enum
enum Direction {
Up,
Down,
Left,
Right,
}
// 8. Type guards
function isString(value: any): value is string {
return typeof value === 'string';
}
function process(value: string | number) {
if (isString(value)) {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(2));
}
}
// instanceof guard
class Dog {
bark() {
console.log('Woof!');
}
}
class Cat {
meow() {
console.log('Meow!');
}
}
function makeSound(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}
// 9. Utility types
// Partial - makes all properties optional
interface TodoItem {
title: string;
description: string;
completed: boolean;
}
function updateTodo(todo: TodoItem, updates: Partial<TodoItem>): TodoItem {
return { ...todo, ...updates };
}
// Required - makes all properties required
type RequiredTodo = Required<Partial<TodoItem>>;
// Readonly - makes all properties readonly
const readonlyTodo: Readonly<TodoItem> = {
title: 'Learn TypeScript',
description: 'Study TS fundamentals',
completed: false,
};
// readonlyTodo.completed = true; // Error: readonly
// Pick - select specific properties
type TodoPreview = Pick<TodoItem, 'title' | 'completed'>;
// Omit - exclude specific properties
type TodoInfo = Omit<TodoItem, 'completed'>;
// Record - create object type with specific keys
type PageInfo = Record<'home' | 'about' | 'contact', { title: string }>;
const pages: PageInfo = {
home: { title: 'Home' },
about: { title: 'About' },
contact: { title: 'Contact' },
};
// 10. Advanced types
// Mapped types
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
type NullableUser = Nullable<User>;
// Conditional types
type NonNullable<T> = T extends null | undefined ? never : T;
type NotNull = NonNullable<string | null>; // string
// Template literal types
type EventName = 'click' | 'focus' | 'blur';
type EventHandler = `on${Capitalize<EventName>}`;
// Result: 'onClick' | 'onFocus' | 'onBlur'
import React, { useState, useEffect } from 'react';
// 1. Functional component with props
interface ButtonProps {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
disabled?: boolean;
}
const Button: React.FC<ButtonProps> = ({
label,
onClick,
variant = 'primary',
disabled = false,
}) => {
return (
<button
onClick={onClick}
disabled={disabled}
className={`btn btn-${variant}`}
>
{label}
</button>
);
};
// 2. Component with children
interface CardProps {
title: string;
children: React.ReactNode;
}
const Card: React.FC<CardProps> = ({ title, children }) => {
return (
<div className="card">
<h3>{title}</h3>
<div className="card-body">{children}</div>
</div>
);
};
// 3. useState with types
const Counter: React.FC = () => {
const [count, setCount] = useState<number>(0);
const [name, setName] = useState<string>('');
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
};
// 4. Complex state types
interface Todo {
id: number;
text: string;
completed: boolean;
}
const TodoList: React.FC = () => {
const [todos, setTodos] = useState<Todo[]>([]);
const addTodo = (text: string) => {
const newTodo: Todo = {
id: Date.now(),
text,
completed: false,
};
setTodos([...todos, newTodo]);
};
const toggleTodo = (id: number) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
));
};
return (
<ul>
{todos.map(todo => (
<li key={todo.id} onClick={() => toggleTodo(todo.id)}>
{todo.text}
</li>
))}
</ul>
);
};
// 5. Event handlers
const Form: React.FC = () => {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
// Handle form
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value);
};
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
console.log('Clicked!');
};
return (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} />
<button onClick={handleClick}>Submit</button>
</form>
);
};
// 6. Custom hooks
function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T) => void] {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setValue = (value: T) => {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
};
return [storedValue, setValue];
}
// Usage
const App: React.FC = () => {
const [name, setName] = useLocalStorage<string>('name', '');
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
};