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;
    }

  2. Variables without initial values

    let username: string;
    username = "alice"; // Later assignment

  3. Complex types that are hard to infer

    let data: { name: string; age: number }[] = [];

  4. 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}`;
    }

  2. Using any instead of proper types

    // ❌ Bad
    let data: any = fetchData();
    
    // ✅ Good
    let data: UserData = fetchData();

  3. 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.