Prerequisites
- TypeScript installed on your system โก
- Basic understanding of programming concepts ๐
- A code editor (VS Code recommended) ๐ป
What you'll learn
- Write and run your first TypeScript program ๐ฏ
- Understand TypeScript file structure and compilation ๐๏ธ
- Create interactive programs with user input ๐ฌ
- Build confidence with TypeScript basics โจ
๐ฏ Introduction
Welcome to your first TypeScript adventure! ๐ Today, weโre going beyond โHello Worldโ to build real, interactive programs that showcase TypeScriptโs power.
Youโll discover how to write, compile, and run TypeScript programs while learning essential concepts along the way. Weโll start simple and gradually add features, so by the end, youโll have created several mini-programs you can be proud of!
Ready to write some TypeScript? Letโs make something awesome! ๐
๐ Understanding TypeScript Programs
๐ค What Makes a TypeScript Program?
A TypeScript program is like a recipe ๐ with precise instructions. Unlike JavaScriptโs โadd ingredients to tasteโ approach, TypeScript wants you to specify exactly what goes in - making your recipes (programs) more reliable!
Every TypeScript program consists of:
- โจ Type annotations (the secret sauce)
- ๐ Modern JavaScript features
- ๐ก๏ธ Compile-time safety checks
- ๐ Clear, self-documenting code
๐ก The TypeScript Workflow
Hereโs how TypeScript programs come to life:
- Write ๐: Create
.ts
files with TypeScript code - Compile ๐ ๏ธ: TypeScript compiler (
tsc
) converts to JavaScript - Run ๐: Execute the generated JavaScript with Node.js or browser
- Debug ๐: Use source maps to debug original TypeScript
๐ง Your First Program: Hello TypeScript!
๐ Step 1: Create Your First File
Create a new file called hello.ts
:
// ๐ hello.ts - Your first TypeScript program!
// ๐ฏ A simple greeting function with types
function greet(name: string, language: string = "TypeScript"): string {
return `Hello, ${name}! Welcome to ${language}! ๐`;
}
// ๐ Using our function
const userName: string = "Developer";
const greeting: string = greet(userName);
console.log(greeting);
console.log("๐ Your TypeScript journey begins now!");
// ๐ก Let's add some interactivity
const currentTime: Date = new Date();
const hour: number = currentTime.getHours();
// ๐จ Time-based greetings with emojis!
let timeGreeting: string;
let emoji: string;
if (hour < 12) {
timeGreeting = "Good morning";
emoji = "๐
";
} else if (hour < 18) {
timeGreeting = "Good afternoon";
emoji = "โ๏ธ";
} else {
timeGreeting = "Good evening";
emoji = "๐";
}
console.log(`${emoji} ${timeGreeting}, ${userName}!`);
๐ฏ Step 2: Compile and Run
# ๐ ๏ธ Compile TypeScript to JavaScript
tsc hello.ts
# ๐ This creates hello.js
# ๐ Run the program
node hello.js
Output:
Hello, Developer! Welcome to TypeScript! ๐
๐ Your TypeScript journey begins now!
๐
Good morning, Developer!
๐ก Practical Examples
๐ Example 1: Interactive Shopping List
Letโs build something more interactive:
// ๐ shopping-list.ts
// ๐๏ธ Define our shopping item structure
interface ShoppingItem {
id: number;
name: string;
quantity: number;
purchased: boolean;
emoji: string;
}
// ๐ Shopping list manager class
class ShoppingList {
private items: ShoppingItem[] = [];
private nextId: number = 1;
// โ Add item to list
addItem(name: string, quantity: number = 1, emoji: string = "๐ฆ"): void {
const newItem: ShoppingItem = {
id: this.nextId++,
name,
quantity,
purchased: false,
emoji
};
this.items.push(newItem);
console.log(`โ
Added ${emoji} ${name} (ร${quantity}) to your list!`);
}
// ๐๏ธ Mark item as purchased
purchaseItem(id: number): void {
const item = this.items.find(i => i.id === id);
if (item && !item.purchased) {
item.purchased = true;
console.log(`๐ Purchased ${item.emoji} ${item.name}!`);
}
}
// ๐ Display the list
displayList(): void {
console.log("\n๐ Your Shopping List:");
console.log("โโโโโโโโโโโโโโโโโโโโโโโ");
if (this.items.length === 0) {
console.log(" ๐ Your list is empty!");
return;
}
this.items.forEach(item => {
const status = item.purchased ? "โ
" : "โณ";
const strikethrough = item.purchased ? "~~" : "";
console.log(` ${status} ${item.emoji} ${strikethrough}${item.name}${strikethrough} (ร${item.quantity})`);
});
// ๐ Statistics
const purchased = this.items.filter(i => i.purchased).length;
const total = this.items.length;
const percentage = total > 0 ? Math.round((purchased / total) * 100) : 0;
console.log("โโโโโโโโโโโโโโโโโโโโโโโ");
console.log(`๐ Progress: ${purchased}/${total} items (${percentage}%)`);
}
}
// ๐ฎ Let's use our shopping list!
console.log("๐ Welcome to TypeScript Shopping List! ๐\n");
const myList = new ShoppingList();
// ๐๏ธ Add some items
myList.addItem("TypeScript Book", 1, "๐");
myList.addItem("Coffee", 3, "โ");
myList.addItem("Laptop Sticker", 5, "๐ป");
myList.addItem("Energy Drink", 2, "โก");
// ๐ Show initial list
myList.displayList();
// ๐๏ธ Purchase some items
console.log("\n๐๏ธ Shopping time!");
myList.purchaseItem(1);
myList.purchaseItem(2);
// ๐ Show updated list
myList.displayList();
๐ฎ Example 2: Number Guessing Game
Letโs create an interactive game:
// ๐ guess-game.ts
// ๐ฏ Game configuration interface
interface GameConfig {
minNumber: number;
maxNumber: number;
maxAttempts: number;
difficulty: "easy" | "medium" | "hard";
}
// ๐ฎ Game statistics
interface GameStats {
gamesPlayed: number;
gamesWon: number;
totalAttempts: number;
bestScore: number;
}
// ๐ฒ Number guessing game class
class NumberGuessingGame {
private secretNumber: number = 0;
private attempts: number = 0;
private config: GameConfig;
private stats: GameStats = {
gamesPlayed: 0,
gamesWon: 0,
totalAttempts: 0,
bestScore: Infinity
};
constructor(difficulty: "easy" | "medium" | "hard" = "medium") {
this.config = this.getDifficultyConfig(difficulty);
console.log(`๐ฎ Game created in ${difficulty} mode!`);
}
// ๐ฏ Get difficulty configuration
private getDifficultyConfig(difficulty: string): GameConfig {
const configs: Record<string, GameConfig> = {
easy: { minNumber: 1, maxNumber: 10, maxAttempts: 5, difficulty: "easy" },
medium: { minNumber: 1, maxNumber: 50, maxAttempts: 7, difficulty: "medium" },
hard: { minNumber: 1, maxNumber: 100, maxAttempts: 10, difficulty: "hard" }
};
return configs[difficulty] || configs.medium;
}
// ๐ฒ Start a new game
startNewGame(): void {
this.secretNumber = Math.floor(Math.random() *
(this.config.maxNumber - this.config.minNumber + 1)) + this.config.minNumber;
this.attempts = 0;
this.stats.gamesPlayed++;
console.log("\n๐ New Game Started!");
console.log(`๐ฏ I'm thinking of a number between ${this.config.minNumber} and ${this.config.maxNumber}`);
console.log(`๐ก You have ${this.config.maxAttempts} attempts. Good luck! ๐`);
}
// ๐ค Make a guess
makeGuess(guess: number): boolean {
this.attempts++;
this.stats.totalAttempts++;
if (guess === this.secretNumber) {
console.log(`\n๐ CORRECT! You got it in ${this.attempts} attempts!`);
this.stats.gamesWon++;
if (this.attempts < this.stats.bestScore) {
this.stats.bestScore = this.attempts;
console.log(`๐ NEW BEST SCORE: ${this.attempts} attempts!`);
}
this.showStats();
return true;
}
const remainingAttempts = this.config.maxAttempts - this.attempts;
if (remainingAttempts === 0) {
console.log(`\n๐ข Game Over! The number was ${this.secretNumber}`);
this.showStats();
return true;
}
// ๐ฏ Give hints
const difference = Math.abs(guess - this.secretNumber);
let hint: string;
let emoji: string;
if (guess < this.secretNumber) {
hint = "Too low!";
emoji = "๐";
} else {
hint = "Too high!";
emoji = "๐";
}
// ๐ฅ Temperature hints
let temperature: string;
if (difference <= 2) {
temperature = "๐ฅ You're burning hot!";
} else if (difference <= 5) {
temperature = "โจ๏ธ Getting warmer!";
} else if (difference <= 10) {
temperature = "๐ก๏ธ Warm...";
} else {
temperature = "โ๏ธ Cold!";
}
console.log(`${emoji} ${hint} ${temperature}`);
console.log(`๐ซ ${remainingAttempts} attempts remaining`);
return false;
}
// ๐ Show game statistics
private showStats(): void {
const winRate = this.stats.gamesPlayed > 0
? Math.round((this.stats.gamesWon / this.stats.gamesPlayed) * 100)
: 0;
console.log("\n๐ Your Statistics:");
console.log(` ๐ฎ Games Played: ${this.stats.gamesPlayed}`);
console.log(` ๐ Games Won: ${this.stats.gamesWon}`);
console.log(` ๐ Win Rate: ${winRate}%`);
console.log(` ๐ฏ Best Score: ${this.stats.bestScore === Infinity ? "N/A" : this.stats.bestScore} attempts`);
}
}
// ๐ฎ Demo the game
console.log("๐ฒ Welcome to TypeScript Number Guessing Game!\n");
const game = new NumberGuessingGame("medium");
game.startNewGame();
// ๐ฏ Simulate some guesses
console.log("\n๐ค Making guesses...");
game.makeGuess(25);
game.makeGuess(35);
game.makeGuess(30);
game.makeGuess(32);
๐ Advanced Concepts
๐งโโ๏ธ Adding Type Safety to User Input
Hereโs how to handle user input safely:
// ๐ user-input.ts
// ๐ฏ Input validation with types
interface ValidationResult {
isValid: boolean;
value?: any;
error?: string;
}
// ๐ก๏ธ Input validator class
class InputValidator {
// ๐ข Validate number input
static validateNumber(input: string, min?: number, max?: number): ValidationResult {
const num = parseFloat(input);
if (isNaN(num)) {
return { isValid: false, error: "โ Please enter a valid number!" };
}
if (min !== undefined && num < min) {
return { isValid: false, error: `โ Number must be at least ${min}` };
}
if (max !== undefined && num > max) {
return { isValid: false, error: `โ Number must be at most ${max}` };
}
return { isValid: true, value: num };
}
// ๐ Validate string input
static validateString(input: string, minLength?: number, maxLength?: number): ValidationResult {
const trimmed = input.trim();
if (!trimmed) {
return { isValid: false, error: "โ Input cannot be empty!" };
}
if (minLength && trimmed.length < minLength) {
return { isValid: false, error: `โ Must be at least ${minLength} characters` };
}
if (maxLength && trimmed.length > maxLength) {
return { isValid: false, error: `โ Must be at most ${maxLength} characters` };
}
return { isValid: true, value: trimmed };
}
// ๐ง Validate email
static validateEmail(input: string): ValidationResult {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(input)) {
return { isValid: false, error: "โ Please enter a valid email!" };
}
return { isValid: true, value: input.toLowerCase() };
}
}
// ๐ฎ Demo input validation
console.log("๐ก๏ธ TypeScript Input Validation Demo\n");
// Test cases
const testInputs = [
{ type: "number", value: "42", validator: () => InputValidator.validateNumber("42", 0, 100) },
{ type: "number", value: "abc", validator: () => InputValidator.validateNumber("abc") },
{ type: "string", value: "TypeScript", validator: () => InputValidator.validateString("TypeScript", 5, 20) },
{ type: "email", value: "[email protected]", validator: () => InputValidator.validateEmail("[email protected]") },
{ type: "email", value: "invalid-email", validator: () => InputValidator.validateEmail("invalid-email") }
];
testInputs.forEach(test => {
const result = test.validator();
console.log(`Testing ${test.type}: "${test.value}"`);
if (result.isValid) {
console.log(` โ
Valid! Value: ${result.value}`);
} else {
console.log(` ${result.error}`);
}
});
๐๏ธ Building a Complete CLI Program
// ๐ todo-cli.ts
// ๐ฏ A complete command-line todo app
interface Todo {
id: number;
text: string;
completed: boolean;
priority: "low" | "medium" | "high";
createdAt: Date;
emoji: string;
}
interface Command {
name: string;
description: string;
emoji: string;
execute: (args: string[]) => void;
}
class TodoCLI {
private todos: Todo[] = [];
private nextId: number = 1;
private commands: Map<string, Command> = new Map();
constructor() {
this.setupCommands();
this.showWelcome();
}
// ๐ ๏ธ Setup available commands
private setupCommands(): void {
const commands: Command[] = [
{
name: "add",
description: "Add a new todo",
emoji: "โ",
execute: (args) => this.addTodo(args.join(" "))
},
{
name: "list",
description: "List all todos",
emoji: "๐",
execute: () => this.listTodos()
},
{
name: "complete",
description: "Mark todo as complete",
emoji: "โ
",
execute: (args) => this.completeTodo(parseInt(args[0]))
},
{
name: "help",
description: "Show help",
emoji: "โ",
execute: () => this.showHelp()
}
];
commands.forEach(cmd => this.commands.set(cmd.name, cmd));
}
// ๐ Show welcome message
private showWelcome(): void {
console.log("๐ฏ Welcome to TypeScript Todo CLI!");
console.log("๐ Manage your tasks with style!\n");
this.showHelp();
}
// โ Show help
private showHelp(): void {
console.log("๐ Available Commands:");
this.commands.forEach(cmd => {
console.log(` ${cmd.emoji} ${cmd.name.padEnd(10)} - ${cmd.description}`);
});
console.log("\n๐ก Example: add Learn TypeScript");
}
// โ Add todo
private addTodo(text: string): void {
if (!text) {
console.log("โ Please provide todo text!");
return;
}
const todo: Todo = {
id: this.nextId++,
text,
completed: false,
priority: "medium",
createdAt: new Date(),
emoji: "๐"
};
this.todos.push(todo);
console.log(`โ
Added: ${todo.emoji} ${todo.text}`);
}
// ๐ List todos
private listTodos(): void {
if (this.todos.length === 0) {
console.log("๐ญ No todos yet! Add one with 'add <text>'");
return;
}
console.log("\n๐ Your Todos:");
this.todos.forEach(todo => {
const status = todo.completed ? "โ
" : "โณ";
console.log(` ${status} [${todo.id}] ${todo.text}`);
});
}
// โ
Complete todo
private completeTodo(id: number): void {
const todo = this.todos.find(t => t.id === id);
if (!todo) {
console.log("โ Todo not found!");
return;
}
todo.completed = true;
console.log(`โ
Completed: ${todo.text}`);
}
}
// ๐ Run the CLI
const cli = new TodoCLI();
โ ๏ธ Common Pitfalls and Solutions
๐ฑ Pitfall 1: Forgetting to Compile
# โ Wrong - Trying to run TypeScript directly
node my-program.ts
# Error: Unexpected token ':'
# โ
Correct - Compile first
tsc my-program.ts
node my-program.js
# ๐ Or use ts-node for development
npx ts-node my-program.ts
๐คฏ Pitfall 2: Type Errors in Simple Programs
// โ Common beginner mistake
let count = 0;
count = "zero"; // Error: Type 'string' is not assignable to type 'number'
// โ
Solution 1: Keep consistent types
let count = 0;
count = 1; // Good!
// โ
Solution 2: Use union types if needed
let count: number | string = 0;
count = "zero"; // Now it works!
๐ต Pitfall 3: Missing Return Types
// โ Implicit any return type
function calculate(a: number, b: number) {
return a + b; // TypeScript infers number, but it's better to be explicit
}
// โ
Explicit return type
function calculate(a: number, b: number): number {
return a + b;
}
๐ ๏ธ Best Practices
- ๐ฏ Always specify types: Even when TypeScript can infer
- ๐ Use meaningful variable names:
userName
notun
- ๐ก๏ธ Enable strict mode: Maximum type safety
- ๐จ Organize with interfaces: Define shapes of your data
- โจ Keep it simple: Start basic, add complexity gradually
๐งช Hands-On Exercise
๐ฏ Challenge: Build a Temperature Converter
Create a TypeScript program that:
๐ Requirements:
- โ Converts between Celsius, Fahrenheit, and Kelvin
- ๐ท๏ธ Uses proper types for temperature values
- ๐ค Validates input (no temperatures below absolute zero)
- ๐ Tracks conversion history
- ๐จ Shows results with weather-appropriate emojis
๐ Bonus Features:
- Add โfeels likeโ descriptions
- Support batch conversions
- Export results to formatted text
๐ก Solution
๐ Click to see solution
// ๐ก๏ธ Temperature converter solution
type TemperatureUnit = "C" | "F" | "K";
interface Temperature {
value: number;
unit: TemperatureUnit;
}
interface ConversionRecord {
from: Temperature;
to: Temperature;
timestamp: Date;
}
class TemperatureConverter {
private history: ConversionRecord[] = [];
// ๐ Convert temperature
convert(value: number, fromUnit: TemperatureUnit, toUnit: TemperatureUnit): number {
// First convert to Celsius
let celsius: number;
switch (fromUnit) {
case "C":
celsius = value;
break;
case "F":
celsius = (value - 32) * 5/9;
break;
case "K":
celsius = value - 273.15;
break;
}
// Validate (can't go below absolute zero)
if (celsius < -273.15) {
throw new Error("โ Temperature below absolute zero!");
}
// Convert from Celsius to target unit
let result: number;
switch (toUnit) {
case "C":
result = celsius;
break;
case "F":
result = celsius * 9/5 + 32;
break;
case "K":
result = celsius + 273.15;
break;
}
// Record conversion
this.history.push({
from: { value, unit: fromUnit },
to: { value: result, unit: toUnit },
timestamp: new Date()
});
return result;
}
// ๐ก๏ธ Get weather emoji based on Celsius
private getWeatherEmoji(celsius: number): string {
if (celsius < -10) return "๐ฅถ";
if (celsius < 0) return "โ๏ธ";
if (celsius < 10) return "๐ง";
if (celsius < 20) return "๐ค๏ธ";
if (celsius < 30) return "โ๏ธ";
if (celsius < 40) return "๐ฅ";
return "๐";
}
// ๐ Display conversion with emoji
displayConversion(value: number, fromUnit: TemperatureUnit, toUnit: TemperatureUnit): void {
try {
const result = this.convert(value, fromUnit, toUnit);
const celsiusValue = fromUnit === "C" ? value : this.convert(value, fromUnit, "C");
const emoji = this.getWeatherEmoji(celsiusValue);
console.log(`${emoji} ${value}ยฐ${fromUnit} = ${result.toFixed(2)}ยฐ${toUnit}`);
// Add description
if (celsiusValue < 0) {
console.log(" ๐ง Below freezing!");
} else if (celsiusValue > 30) {
console.log(" ๐๏ธ Beach weather!");
} else if (celsiusValue > 20) {
console.log(" ๐ T-shirt weather!");
} else {
console.log(" ๐งฅ Jacket recommended!");
}
} catch (error) {
console.log(error.message);
}
}
// ๐ Show conversion history
showHistory(): void {
console.log("\n๐ Conversion History:");
this.history.forEach((record, index) => {
console.log(` ${index + 1}. ${record.from.value}ยฐ${record.from.unit} โ ${record.to.value.toFixed(2)}ยฐ${record.to.unit}`);
});
}
}
// ๐ฎ Demo the converter
console.log("๐ก๏ธ TypeScript Temperature Converter\n");
const converter = new TemperatureConverter();
// Test conversions
converter.displayConversion(25, "C", "F");
converter.displayConversion(32, "F", "C");
converter.displayConversion(300, "K", "C");
converter.displayConversion(100, "C", "K");
converter.showHistory();
๐ Key Takeaways
Youโve successfully written your first TypeScript programs! Hereโs what youโve learned:
- โ Created TypeScript files and compiled them ๐ช
- โ Used types for variables, functions, and objects ๐ก๏ธ
- โ Built interactive programs with classes and interfaces ๐ฏ
- โ Handled user input safely with validation ๐
- โ Applied best practices from the start! ๐
Remember: Every expert TypeScript developer started with a simple โHello Worldโ! ๐
๐ค Next Steps
Congratulations! ๐ Youโve written real TypeScript programs!
Hereโs what to do next:
- ๐ป Complete the temperature converter challenge
- ๐๏ธ Expand one of the examples with your own features
- ๐ Try the TypeScript Playground online
- ๐ Share your first program with others!
Remember: The best way to learn is by building. Keep coding! ๐
Happy coding! ๐๐โจ