You are viewing a preview of this lesson. Sign in to start learning
Back to TypeScript

Getting Started

Learn TypeScript fundamentals, installation process, and project setup to begin your development journey.

Getting Started with TypeScript

Master TypeScript fundamentals with free flashcards and spaced repetition practice to reinforce your learning. This lesson covers TypeScript installation, basic type annotations, configuration setup, and your first TypeScript programβ€”essential concepts for modern JavaScript development with type safety.

Welcome to TypeScript! πŸ’»

Welcome to the exciting world of TypeScript! If you've been writing JavaScript and wondering how to catch bugs before runtime, add better IDE support, and make your code more maintainable, you're in the right place. TypeScript is a superset of JavaScript that adds static typing and other powerful features to help you write better code.

TypeScript = JavaScript + Static Types + Modern Features

Think of TypeScript as JavaScript with guardrails. It compiles down to plain JavaScript, so it runs anywhere JavaScript runsβ€”browsers, Node.js, mobile apps, and more. The TypeScript compiler acts as your safety net, catching errors during development rather than in production.

πŸ’‘ Did you know? TypeScript was created by Microsoft in 2012 and is now maintained by Anders Hejlsberg, the same person who designed C#. It has become the de facto standard for large-scale JavaScript applications, used by companies like Google, Airbnb, and Slack.

Core Concepts 🎯

What is TypeScript?

TypeScript is a statically typed superset of JavaScript that compiles to plain JavaScript. Let's break that down:

  • Superset: Every valid JavaScript file is also a valid TypeScript file (just rename .js to .ts)
  • Statically typed: Types are checked at compile-time, not runtime
  • Compiled: TypeScript code is transformed into JavaScript before execution
JavaScriptTypeScript
Dynamic typingStatic typing
No compile stepCompiles to JS
Runtime errorsCompile-time errors
Limited IDE supportExcellent IDE support

Why Use TypeScript?

1. Early Error Detection πŸ›

TypeScript catches errors before you run your code:

// JavaScript - Error at runtime
function greet(name) {
  return "Hello, " + name.toUppercase(); // Typo! Runtime error
}
// TypeScript - Error at compile-time
function greet(name: string) {
  return "Hello, " + name.toUppercase(); // ❌ Compiler catches typo!
  // Property 'toUppercase' does not exist. Did you mean 'toUpperCase'?
}

2. Better IDE Support πŸ”§

With types, your editor can provide:

  • Autocomplete: See available methods and properties
  • Refactoring: Rename variables safely across your entire project
  • Inline documentation: See function signatures as you type
  • Go to definition: Jump to source code instantly

3. Self-Documenting Code πŸ“–

Types serve as inline documentation:

// Without types - what does this function expect?
function createUser(name, age, email) { /*...*/ }

// With types - crystal clear!
function createUser(name: string, age: number, email: string): User { /*...*/ }

4. Easier Refactoring ♻️

Change a function signature and TypeScript tells you everywhere it breaks.

Installing TypeScript πŸ“¦

Method 1: Global Installation (recommended for learning)

npm install -g typescript

Verify installation:

tsc --version
# Output: Version 5.3.3 (or similar)

Method 2: Local Project Installation (recommended for projects)

mkdir my-typescript-project
cd my-typescript-project
npm init -y
npm install --save-dev typescript

Add to package.json scripts:

{
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch"
  }
}

πŸ’‘ Pro tip: Use npx tsc to run locally installed TypeScript without adding it to PATH.

The TypeScript Compiler (tsc) βš™οΈ

The TypeScript Compiler (tsc) transforms .ts files into .js files:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  TypeScript Compilation Process     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  πŸ“„ hello.ts (TypeScript)
       β”‚
       ↓
  πŸ”§ tsc (TypeScript Compiler)
       β”‚
       β”œβ”€β”€β†’ Type checking
       β”œβ”€β”€β†’ Transpilation
       └──→ ES version conversion
       β”‚
       ↓
  πŸ“„ hello.js (JavaScript)
       β”‚
       ↓
  🌐 Browser / Node.js

Basic compiler commands:

# Compile a single file
tsc hello.ts

# Compile all files in project
tsc

# Watch mode - recompile on changes
tsc --watch

# Compile and set ECMAScript target
tsc --target ES2020 hello.ts

TypeScript Configuration (tsconfig.json) πŸ“‹

The tsconfig.json file controls how TypeScript compiles your project. Create one with:

tsc --init

This generates a configuration file with sensible defaults. Here's a starter configuration:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
OptionPurpose
targetJavaScript version to compile to (ES5, ES2020, etc.)
moduleModule system (commonjs, ES6, etc.)
strictEnable all strict type-checking options
outDirOutput directory for compiled files
rootDirRoot directory of source files

πŸ’‘ Tip: Start with "strict": true to get the full TypeScript experience. You can relax individual strict options later if needed.

Basic Type Annotations 🏷️

TypeScript's core feature is type annotationsβ€”explicitly declaring what type a variable should be:

// Basic types
let name: string = "Alice";
let age: number = 30;
let isStudent: boolean = false;
let nothing: null = null;
let notDefined: undefined = undefined;

Type Inference 🧠

TypeScript can often infer types automatically:

let name = "Alice"; // TypeScript infers: string
let age = 30;       // TypeScript infers: number

// No need to write:
let name: string = "Alice";

🎯 Best practice: Let TypeScript infer when obvious, annotate when clarification helps.

Arrays and Objects

// Arrays
let numbers: number[] = [1, 2, 3, 4];
let names: string[] = ["Alice", "Bob"];
let mixed: (number | string)[] = [1, "two", 3];

// Alternative array syntax
let numbers: Array<number> = [1, 2, 3];

// Objects
let user: { name: string; age: number } = {
  name: "Alice",
  age: 30
};

Functions

// Function with typed parameters and return type
function add(a: number, b: number): number {
  return a + b;
}

// Arrow function
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 greet(name: string, greeting: string = "Hello"): string {
  return `${greeting}, ${name}!`;
}

Project Structure πŸ“

A typical TypeScript project structure:

my-typescript-project/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts
β”‚   β”œβ”€β”€ utils.ts
β”‚   └── types.ts
β”œβ”€β”€ dist/
β”‚   └── (compiled .js files)
β”œβ”€β”€ node_modules/
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── .gitignore

Practical Examples πŸš€

Example 1: Your First TypeScript File

Let's create a simple TypeScript program:

Step 1: Create hello.ts

function greet(name: string): string {
  return `Hello, ${name}!`;
}

const userName: string = "TypeScript Developer";
const message: string = greet(userName);

console.log(message);

Step 2: Compile it

tsc hello.ts

This creates hello.js:

function greet(name) {
    return "Hello, " + name + "!";
}
var userName = "TypeScript Developer";
var message = greet(userName);
console.log(message);

Step 3: Run it

node hello.js
# Output: Hello, TypeScript Developer!

πŸ’‘ Notice: The types are removed in the compiled JavaScriptβ€”TypeScript types only exist during development.

Example 2: Type Safety in Action

Let's see how TypeScript catches errors:

function calculateArea(width: number, height: number): number {
  return width * height;
}

// βœ… Correct usage
const area1 = calculateArea(10, 20); // 200

// ❌ TypeScript catches errors
const area2 = calculateArea("10", 20);
// Error: Argument of type 'string' is not assignable to parameter of type 'number'

const area3 = calculateArea(10);
// Error: Expected 2 arguments, but got 1

const area4: string = calculateArea(10, 20);
// Error: Type 'number' is not assignable to type 'string'

Real-world scenario: Imagine catching these errors at compile-time rather than discovering them in production when a user enters unexpected data!

Example 3: Setting Up a Project

Let's create a complete TypeScript project from scratch:

# Create project directory
mkdir todo-app
cd todo-app

# Initialize npm project
npm init -y

# Install TypeScript
npm install --save-dev typescript

# Create TypeScript config
npx tsc --init

# Create source directory
mkdir src

Create src/index.ts:

interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

class TodoList {
  private todos: Todo[] = [];
  private nextId: number = 1;

  addTodo(title: string): void {
    const todo: Todo = {
      id: this.nextId++,
      title: title,
      completed: false
    };
    this.todos.push(todo);
  }

  getTodos(): Todo[] {
    return this.todos;
  }

  completeTodo(id: number): void {
    const todo = this.todos.find(t => t.id === id);
    if (todo) {
      todo.completed = true;
    }
  }
}

// Usage
const myTodos = new TodoList();
myTodos.addTodo("Learn TypeScript");
myTodos.addTodo("Build a project");
myTodos.completeTodo(1);

console.log(myTodos.getTodos());

Update tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src"
  }
}

Compile and run:

npx tsc
node dist/index.js

Example 4: Watch Mode for Development

When developing, use watch mode to automatically recompile on changes:

# Terminal 1: Watch for changes
npx tsc --watch

# Terminal 2: Run with nodemon for auto-restart
npm install --save-dev nodemon
npx nodemon dist/index.js

Or add to package.json:

{
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch",
    "start": "node dist/index.js",
    "dev": "tsc && nodemon dist/index.js"
  }
}

Now run:

npm run watch  # Auto-compile on changes
npm run dev    # Build and run with auto-restart

Common Mistakes ⚠️

1. Forgetting to Compile

// hello.ts
console.log("Hello TypeScript!");
# ❌ Wrong: Trying to run TypeScript directly
node hello.ts
# Error: Unexpected token ':'

# βœ… Correct: Compile first
tsc hello.ts
node hello.js

πŸ’‘ Solution: Always compile with tsc before running, or use ts-node for direct execution:

npm install -g ts-node
ts-node hello.ts

2. Ignoring Type Errors

function divide(a: number, b: number): number {
  return a / b;
}

const result = divide(10, "2"); // ❌ Type error!

❌ Wrong approach: Using // @ts-ignore to suppress errors:

// @ts-ignore
const result = divide(10, "2"); // Compiles but breaks at runtime!

βœ… Correct approach: Fix the type error:

const result = divide(10, 2); // βœ… Correct types
// Or convert if needed:
const result = divide(10, Number("2"));

3. Using any Type Everywhere

// ❌ Defeats the purpose of TypeScript
function process(data: any): any {
  return data.value.toUpperCase();
}

βœ… Better approach: Use specific types:

interface Data {
  value: string;
}

function process(data: Data): string {
  return data.value.toUpperCase();
}

🧠 Remember: The any type turns off TypeScript's type checking. Use it sparingly, only when absolutely necessary.

4. Not Using strict Mode

// ❌ tsconfig.json without strict mode
{
  "compilerOptions": {
    "strict": false  // Misses many potential bugs!
  }
}

βœ… Always enable strict mode:

{
  "compilerOptions": {
    "strict": true  // Catches more errors, better code quality
  }
}

5. Mixing Up Type Annotations and Assertions

// ❌ Type assertion (unsafe)
const myValue = someFunction() as string;

// βœ… Type annotation (safe, compiler-verified)
const myValue: string = someFunction(); // Error if types don't match

Type assertions tell the compiler "trust me, I know better"β€”use them carefully!

Key Takeaways πŸŽ“

βœ… TypeScript is JavaScript with static types that compiles to plain JavaScript

βœ… Install with npm: npm install -g typescript or locally in projects

βœ… Compile with tsc: tsc filename.ts transforms .ts to .js

βœ… Use tsconfig.json to configure compiler options for your project

βœ… Enable strict mode for maximum type safety: "strict": true

βœ… Type annotations explicitly declare variable types: let name: string = "Alice"

βœ… Type inference lets TypeScript figure out types automatically

βœ… Watch mode auto-recompiles on changes: tsc --watch

βœ… Avoid any typeβ€”it disables type checking

βœ… Compile before runningβ€”Node.js can't execute TypeScript directly

🧠 Memory device - The 4 S's of TypeScript:

  • Superset: All JavaScript is valid TypeScript
  • Static: Types checked at compile-time
  • Safe: Catches errors before runtime
  • Scalable: Essential for large codebases

πŸ“š Further Study

  1. Official TypeScript Documentation: https://www.typescriptlang.org/docs/
  2. TypeScript Playground (try TypeScript in browser): https://www.typescriptlang.org/play
  3. TypeScript Deep Dive (free online book): https://basarat.gitbook.io/typescript/

πŸ“‹ Quick Reference Card

Install TypeScriptnpm install -g typescript
Compile filetsc filename.ts
Watch modetsc --watch
Init configtsc --init
Check versiontsc --version
Basic typesstring, number, boolean, array, object
Type annotationlet name: string = "value"
Function typingfunction(x: number): number { }
Enable strict mode"strict": true in tsconfig.json
Run TypeScript directlyts-node filename.ts

Practice Questions

Test your understanding with these questions:

Q1: Write a TypeScript function named `calculateTotal` that takes two parameters (`price` as number and `quantity` as number) and returns their product. Include proper type annotations for parameters and return type.
A: !AI