Understanding how to declare variables and use type annotations in TypeScript.

Variable Declarations

TypeScript supports let, const, and var (though var is discouraged).

let

Block-scoped variable that can be reassigned.

let count: number = 0;
count = 10; // OK

let name: string;
name = "Alice"; // OK

const

Block-scoped constant that cannot be reassigned.

const PI: number = 3.14159;
// PI = 3.14; // ❌ Error: Cannot assign to 'PI'

const user = {
  name: "Alice",
  age: 25
};
user.age = 26; // ✅ OK - object properties can change

var (Avoid!)

Function-scoped, can cause issues. Use let or const instead.

// Don't do this:
var oldStyle = "avoid this";

// Do this instead:
let modernStyle = "use this";
const constantValue = "or this";

Type Annotations

Explicit Type Annotations

let age: number = 25;
let name: string = "Alice";
let isActive: boolean = true;

Type Inference

TypeScript infers types when you provide initial values.

// TypeScript knows these are number, string, and boolean
let age = 25;
let name = "Alice";
let isActive = true;

When to Use Explicit Types

  1. Function parameters and return types
function add(a: number, b: number): number {
  return a + b;
}
  1. Variables without initial values
let username: string;
username = "alice"; // Later assignment
  1. Complex types that are hard to infer
let data: { name: string; age: number }[] = [];
  1. When you want to be explicit for documentation
// Makes intent clear
let userId: number = getUserId();

Multiple Declarations

// Declare multiple variables of the same type
let x: number, y: number, z: number;
x = 1;
y = 2;
z = 3;

// Or initialize them
let a: number = 1, b: number = 2, c: number = 3;

Readonly Modifier

Make properties immutable.

interface Point {
  readonly x: number;
  readonly y: number;
}

let point: Point = { x: 10, y: 20 };
// point.x = 30; // ❌ Error: Cannot assign to 'x' because it is a read-only property

Type Assertions

Tell TypeScript you know more about a type than it does.

// Angle bracket syntax (not allowed in .tsx files)
let value: any = "hello";
let strLength: number = (<string>value).length;

// as syntax (preferred)
let strLength2: number = (value as string).length;

Exercises

Exercise 1: Variable Declarations

// Declare variables with proper types:
// - A number called 'score' initialized to 0
// - A string called 'playerName' without initialization
// - A boolean called 'isGameOver' initialized to false
// - A constant number called 'MAX_SCORE' set to 1000

Exercise 2: Type Inference

// What types are inferred?
let a = 42;
let b = "hello";
let c = [1, 2, 3];
let d = { name: "Alice", age: 25 };

Exercise 3: Readonly

// Create a readonly interface for a configuration object
// with properties: apiUrl (string), timeout (number), retries (number)

Exercise 4: Type Assertions

// You have a value of type 'any'
// Assert it as a number and use it in a calculation
let unknownValue: any = 42;

Best Practices

  1. Prefer const over let - Use let only when reassignment is needed
  2. Avoid var - Use let or const instead
  3. Use type inference - Let TypeScript infer when possible
  4. Be explicit when it helps - Add types for clarity and documentation
  5. Use readonly for immutability - When you want to prevent reassignment

Common Mistakes

  1. Forgetting type annotations on function parameters
// ❌ Bad
function greet(name) {
  return `Hello, ${name}`;
}

// ✅ Good
function greet(name: string): string {
  return `Hello, ${name}`;
}
  1. Using any instead of proper types
// ❌ Bad
let data: any = fetchData();

// ✅ Good
let data: UserData = fetchData();
  1. Not using const for values that don't change
// ❌ Bad
let API_URL = "https://api.example.com";

// ✅ Good
const API_URL = "https://api.example.com";

Next Steps

Learn about Functions.