TypeScript Basics
Learn TypeScript, a strongly typed programming language that builds on JavaScript.
What is TypeScript?
TypeScript is a superset of JavaScript that adds static type definitions. It helps you:
- Catch errors early during development
- Improve code quality with better tooling
- Enhance maintainability of large codebases
- Better IDE support with autocomplete and refactoring
Installation
Global Installation
bash
npm install -g typescript
Project Installation
bash
npm install -D typescript
npm install -D @types/node
Initialize TypeScript Project
bash
npx tsc --init
Basic Types
Primitive Types
typescript
// String
let name: string = "John"
// Number
let age: number = 30
// Boolean
let isActive: boolean = true
// Array
let numbers: number[] = [1, 2, 3]
let names: Array<string> = ["John", "Jane"]
// Tuple
let person: [string, number] = ["John", 30]
// Enum
enum Color {
Red,
Green,
Blue
}
let color: Color = Color.Red
// Any (avoid when possible)
let value: any = 42
// Void
function logMessage(): void {
console.log("Hello")
}
// Null and Undefined
let nullable: null = null
let undefined: undefined = undefined
Object Types
typescript
// Object type
let user: {
name: string
age: number
email?: string // Optional property
} = {
name: "John",
age: 30
}
// Interface
interface User {
name: string
age: number
email?: string
}
let user2: User = {
name: "Jane",
age: 25
}
// Type alias
type Point = {
x: number
y: number
}
let point: Point = { x: 10, y: 20 }
Functions
Function Types
typescript
// Function declaration
function add(a: number, b: number): number {
return a + b
}
// Function expression
const multiply = (a: number, b: number): number => {
return a * b
}
// Optional parameters
function greet(name: string, greeting?: string): string {
return `${greeting || "Hello"}, ${name}!`
}
// Default parameters
function createUser(name: string, age: number = 18): User {
return { name, age }
}
// Rest parameters
function sum(...numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0)
}
Function Overloads
typescript
function combine(a: string, b: string): string
function combine(a: number, b: number): number
function combine(a: any, b: any): any {
return a + b
}
let result1 = combine("Hello", "World") // string
let result2 = combine(1, 2) // number
Classes
Basic Class
typescript
class Animal {
private name: string
protected species: string
public age: number
constructor(name: string, species: string, age: number) {
this.name = name
this.species = species
this.age = age
}
public makeSound(): void {
console.log(`${this.name} makes a sound`)
}
protected getInfo(): string {
return `${this.name} is a ${this.species}`
}
}
class Dog extends Animal {
private breed: string
constructor(name: string, age: number, breed: string) {
super(name, "Dog", age)
this.breed = breed
}
public makeSound(): void {
console.log(`${this.getInfo()} barks`)
}
public getBreed(): string {
return this.breed
}
}
Abstract Classes
typescript
abstract class Shape {
abstract calculateArea(): number
public displayArea(): void {
console.log(`Area: ${this.calculateArea()}`)
}
}
class Circle extends Shape {
constructor(private radius: number) {
super()
}
calculateArea(): number {
return Math.PI * this.radius ** 2
}
}
Interfaces
Basic Interface
typescript
interface Drivable {
speed: number
drive(): void
}
interface Flyable {
altitude: number
fly(): void
}
// Multiple inheritance
class FlyingCar implements Drivable, Flyable {
speed: number = 0
altitude: number = 0
drive(): void {
console.log("Driving on road")
}
fly(): void {
console.log("Flying in air")
}
}
Extending Interfaces
typescript
interface Animal {
name: string
age: number
}
interface Dog extends Animal {
breed: string
bark(): void
}
const myDog: Dog = {
name: "Buddy",
age: 3,
breed: "Golden Retriever",
bark() {
console.log("Woof!")
}
}
Generics
Generic Functions
typescript
function identity<T>(arg: T): T {
return arg
}
let output1 = identity<string>("Hello")
let output2 = identity<number>(42)
// Generic with constraints
interface Lengthwise {
length: number
}
function logLength<T extends Lengthwise>(arg: T): T {
console.log(arg.length)
return arg
}
logLength("Hello") // OK
logLength([1, 2, 3]) // OK
// logLength(42) // Error: number doesn't have length
Generic Classes
typescript
class GenericStorage<T> {
private items: T[] = []
add(item: T): void {
this.items.push(item)
}
get(index: number): T {
return this.items[index]
}
getAll(): T[] {
return this.items
}
}
const stringStorage = new GenericStorage<string>()
stringStorage.add("Hello")
const numberStorage = new GenericStorage<number>()
numberStorage.add(42)
Advanced Types
Union Types
typescript
type StringOrNumber = string | number
function format(value: StringOrNumber): string {
if (typeof value === "string") {
return value.toUpperCase()
}
return value.toString()
}
Intersection Types
typescript
type Person = {
name: string
age: number
}
type Employee = {
employeeId: string
department: string
}
type PersonEmployee = Person & Employee
const employee: PersonEmployee = {
name: "John",
age: 30,
employeeId: "E001",
department: "Engineering"
}
Conditional Types
typescript
type ApiResponse<T> = T extends string
? { message: T }
: { data: T }
type StringResponse = ApiResponse<string> // { message: string }
type NumberResponse = ApiResponse<number> // { data: number }
Utility Types
typescript
interface User {
id: number
name: string
email: string
age: number
}
// Partial - makes all properties optional
type PartialUser = Partial<User>
// Pick - selects specific properties
type UserSummary = Pick<User, 'id' | 'name'>
// Omit - excludes specific properties
type CreateUser = Omit<User, 'id'>
// Required - makes all properties required
type RequiredUser = Required<PartialUser>
// Record - creates object type with specific keys and values
type UserRoles = Record<string, string>
Best Practices
1. Use Strict Mode
json
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true
}
}
2. Prefer Interfaces for Object Shapes
typescript
// Good
interface User {
name: string
age: number
}
// Use type for unions, primitives, computed types
type Status = 'loading' | 'success' | 'error'
3. Use Type Guards
typescript
function isString(value: unknown): value is string {
return typeof value === 'string'
}
function processValue(value: unknown) {
if (isString(value)) {
// TypeScript knows value is string here
console.log(value.toUpperCase())
}
}
4. Avoid any
typescript
// Bad
function process(data: any): any {
return data.someProperty
}
// Good
function process<T>(data: T): T {
return data
}
Next Steps
- Configuration Reference - VitePress configuration
- Deployment Guide - Deploy your TypeScript projects