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
- Function parameters and return types
function add(a: number, b: number): number {
return a + b;
}
- Variables without initial values
let username: string;
username = "alice"; // Later assignment
- Complex types that are hard to infer
let data: { name: string; age: number }[] = [];
- 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
- Prefer
constoverlet- Useletonly when reassignment is needed - Avoid
var- Useletorconstinstead - Use type inference - Let TypeScript infer when possible
- Be explicit when it helps - Add types for clarity and documentation
- Use
readonlyfor immutability - When you want to prevent reassignment
Common Mistakes
- Forgetting type annotations on function parameters
// ❌ Bad
function greet(name) {
return `Hello, ${name}`;
}
// ✅ Good
function greet(name: string): string {
return `Hello, ${name}`;
}
- Using
anyinstead of proper types
// ❌ Bad
let data: any = fetchData();
// ✅ Good
let data: UserData = fetchData();
- Not using
constfor 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.