TypeScript Variables, Types and Enums in 2025: let/const, Type Inference, Enums & Best Practices

1. How do you declare variables with let and const in TypeScript?

Q: Differences between let, const, and var in TypeScript

Variables in TypeScript are declared using let, const, or var (less common). TypeScript adds static typing to JavaScript’s variable declarations.

Use Case: Use let for variables that change; const for immutable values (though object properties can still be modified).

Can you give an example of let and const in TypeScript?


// Declaring variables with let and const
let counter: number = 0;
counter = 10; // Reassignment allowed
console.log(`Counter: ${counter}`); const maxAttempts: number = 3;
// maxAttempts = 5; // Error: Cannot assign to 'maxAttempts' because it is a constant const config: { host: string; port: number } = { host: "localhost", port: 8080 };
config.port = 3000; // Allowed: Modifying object property
console.log(`Config: ${JSON.stringify(config)}`); 

Output:


Counter: 10
Config: {"host":"localhost","port":3000} 

2. What are type inference and explicit typing in TypeScript?

Q: When to use inference vs explicit annotations

Type Inference: TypeScript automatically infers a variable’s type based on its initial value, reducing the need for explicit type annotations.

Explicit Typing: Manually specifying a variable’s type using type annotations.

Use Case: Use inference for simple cases; explicit typing for complex or ambiguous cases.

Can you give an example of type inference vs. explicit typing?


// Type inference vs. explicit typing
// Type inference
let name = "kristal"; // Inferred as string
let count = 42; // Inferred as number
let scores = [1, 2, 3]; // Inferred as number[] // Explicit typing
let username: string = "Sashi";
let attempts: number = 5;
let settings: { theme: string; darkMode: boolean } = { theme: "light", darkMode: false }; // Type inference limitation
let value = true; // Inferred as boolean
// value = "test"; // Error: Type 'string' is not assignable to type 'boolean' // Explicit typing for clarity
let data: any = 123; // Explicit any (avoid when possible)
data = "now a string"; // No error due to any console.log(`Name: ${name}, Count: ${count}, Scores: ${scores}`);
console.log(`Username: ${username}, Attempts: ${attempts}, Settings: ${JSON.stringify(settings)}`);
console.log(`Data: ${data}`); 

Output:


Name: kristal, Count: 42, Scores: 1,2,3
Username: Sashi, Attempts: 5, Settings: {"theme":"light","darkMode":false}
Data: now a string 

3. What are enums in TypeScript?

Q: Numeric, string, and const enums explained

Enums define a set of named constants, either numeric or string-based, to represent a fixed set of values.

Can you give an example of working with enums?


// Working with enums
// Numeric enum
enum Role { User, // 0 Admin, // 1 Guest = 5 // Custom value
} // String enum
enum Status { Pending = "PENDING", Approved = "APPROVED", Rejected = "REJECTED"
} // Const enum
const enum Direction { Up, Down, Left, Right
} // Usage
let userRole: Role = Role.Admin;
let userStatus: Status = Status.Approved;
let move: Direction = Direction.Up; console.log(`Role: ${userRole} (${Role[userRole]})`);
console.log(`Status: ${userStatus}`);
console.log(`Direction: ${move}`); // Note: Direction is inlined in output JS // Enum in function
function getAccessLevel(role: Role): string { switch (role) { case Role.Admin: return "Full access"; case Role.User: return "Limited access"; case Role.Guest: return "View-only access"; default: return "Unknown"; }
} console.log(`Access: ${getAccessLevel(Role.User)}`); 

Output:


Role: 1 (Admin)
Status: APPROVED
Direction: 0
Access: Limited access 

4. Can you provide a comprehensive example of variables, types, and enums in TypeScript?

Q: Full beginner example combining let/const, inference, and enums

Project Structure:


ts-variables-enums/
├── src/
│ └── main.ts
├── tsconfig.json
└── package.json 

main.ts:


// Comprehensive example with let, const, types, and enums
// Enum for user roles
enum Role { Employee = "EMPLOYEE", Manager = "MANAGER", Contractor = "CONTRACTOR"
} // Interface for type safety
interface Employee { name: string; role: Role; salary: number;
} // Variables with let and const
let department: string = "IT"; // Inferred as string
const maxSalary: number = 100000; // Explicit number type // Function with type inference and explicit typing
function promoteEmployee(emp: Employee): Employee { let newSalary: number = emp.salary * 1.1; // Explicit typing if (newSalary > maxSalary) { newSalary = maxSalary; } const updatedEmployee = { // Inferred as Employee ...emp, salary: newSalary, role: emp.role === Role.Employee ? Role.Manager : emp.role }; return updatedEmployee;
} // Usage
const employee: Employee = { name: "kristal", role: Role.Employee, salary: 60000
}; const promoted = promoteEmployee(employee);
console.log(`Department: ${department}`);
console.log(`Promoted Employee: ${JSON.stringify(promoted)}`);
console.log(`Role: ${promoted.role}`); 

package.json:


{ "name": "ts-variables-enums", "version": "1.0.0", "scripts": { "start": "tsc && node dist/main.js", "build": "tsc", "watch": "tsc --watch" }, "devDependencies": { "typescript": "^5.6.2" }
} 

tsconfig.json:


{ "compilerOptions": { "target": "ES2020", "module": "NodeNext", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true }, "include": ["src/**/*"], "exclude": ["node_modules"]
} 

Steps to Run:

  1. Create the project structure.
  2. Install dependencies: npm install.
  3. Compile: npm run build.
  4. Run: npm start.

Output:


Department: IT
Promoted Employee: {"name":"kristal","role":"MANAGER","salary":66000}
Role: MANAGER 

Description:

5. What are common mistakes in TypeScript variables, types, and enums?

Q: Beginner pitfalls to avoid

6. What are best practices for TypeScript variables, types, and enums?

Q: Recommended practices for clean code in 2025

  1. Variables (let/const):
    • Use let for variables that change; const for immutable bindings.
    • Avoid var to prevent scoping issues.
    • Use const for objects/arrays when the reference won’t change.
  2. Type Inference/Explicit Typing:
    • Leverage type inference for simple cases (e.g., let x = 42).
    • Use explicit typing for complex types or public APIs (e.g., function parameters).
    • Avoid any unless absolutely necessary; use unknown for safer dynamic typing.
  3. Enums:
    • Use string enums for readability or when values are used as strings.
    • Use const enum for performance in compile-time scenarios.
    • Define enums for fixed sets of values to improve type safety.
  4. General:
    • Follow TypeScript naming conventions: camelCase for variables, PascalCase for types/enums.
    • Use interfaces or types for complex data structures.
    • Enable strict mode (strict: true in tsconfig.json) for better type checking.
    • Test edge cases (e.g., invalid types, enum mismatches).
    • Use tools like tsc and linters (e.g., eslint) to catch errors.