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
.jsto.ts) - Statically typed: Types are checked at compile-time, not runtime
- Compiled: TypeScript code is transformed into JavaScript before execution
| JavaScript | TypeScript |
|---|---|
| Dynamic typing | Static typing |
| No compile step | Compiles to JS |
| Runtime errors | Compile-time errors |
| Limited IDE support | Excellent 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"]
}
| Option | Purpose |
|---|---|
| target | JavaScript version to compile to (ES5, ES2020, etc.) |
| module | Module system (commonjs, ES6, etc.) |
| strict | Enable all strict type-checking options |
| outDir | Output directory for compiled files |
| rootDir | Root 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
- Official TypeScript Documentation: https://www.typescriptlang.org/docs/
- TypeScript Playground (try TypeScript in browser): https://www.typescriptlang.org/play
- TypeScript Deep Dive (free online book): https://basarat.gitbook.io/typescript/
π Quick Reference Card
| Install TypeScript | npm install -g typescript |
| Compile file | tsc filename.ts |
| Watch mode | tsc --watch |
| Init config | tsc --init |
| Check version | tsc --version |
| Basic types | string, number, boolean, array, object |
| Type annotation | let name: string = "value" |
| Function typing | function(x: number): number { } |
| Enable strict mode | "strict": true in tsconfig.json |
| Run TypeScript directly | ts-node filename.ts |