Type Annotations in TypeScript — Complete Detailed Guide
Type annotations are one of the most important features in TypeScript. They allow you to explicitly tell TypeScript what type of data a variable, parameter, object, or function should contain.
They improve:
- ✅ Type safety
- ✅ Error detection
- ✅ Code readability
- ✅ IDE autocomplete and suggestions
- ✅ Maintainability of large applications
1. What is a Type Annotation?
A type annotation is a way to specify the type of a variable using a colon : followed by the type.
Syntax
let variableName: type = value;
Example
let username: string = "Rahul";
let age: number = 25;
let isStudent: boolean = true;
Here:
usernamemust contain only stringsagemust contain only numbersisStudentmust contain only boolean values
2. Why Type Annotations are Important
Without TypeScript:
let age = 25;
age = "Hello"; // Allowed in JavaScript
This can create bugs.
With TypeScript:
let age: number = 25;
age = "Hello"; // Error
TypeScript catches the mistake before running the program.
3. Basic Type Annotations
A. String Type
Used for text values.
let company: string = "GeeksforGeeks";
Invalid Example
company = 100; // Error
B. Number Type
Used for integers and decimals.
let marks: number = 95;
let price: number = 99.99;
C. Boolean Type
Stores true or false.
let isLoggedIn: boolean = false;
D. Null and Undefined
let emptyValue: null = null;
let data: undefined = undefined;
4. Type Inference vs Type Annotation
TypeScript can automatically detect types.
Type Inference
let city = "Delhi";
TypeScript automatically understands:
let city: string
Explicit Type Annotation
let city: string = "Delhi";
When to Use Explicit Annotations
Use annotations when:
- Working with functions
- Declaring objects
- Creating APIs
- Writing reusable code
- Using complex data structures
5. Function Type Annotations
Functions can have:
- Parameter type annotations
- Return type annotations
Syntax
function functionName(parameter: type): returnType {
return value;
}
Example
function add(a: number, b: number): number {
return a + b;
}
Explanation
| Part | Meaning |
|---|---|
a: number |
a must be a number |
b: number |
b must be a number |
: number |
function returns a number |
Invalid Example
add(5, "10");
❌ Error because "10" is a string.
6. Void Return Type
Used when a function returns nothing.
function message(): void {
console.log("Welcome");
}
7. Optional Parameters
Use ? for optional values.
function greet(name?: string): void {
console.log(name);
}
You can call:
greet();
greet("Rahul");
8. Default Parameters
function greet(name: string = "Guest"): string {
return `Hello ${name}`;
}
9. Object Type Annotations
Objects can have fixed property types.
Syntax
let obj: { property: type };
Example
let student: { name: string; age: number } = {
name: "Aman",
age: 21
};
Invalid Example
student.age = "Twenty";
❌ Error because age must be a number.
10. Nested Object Types
let employee: {
name: string;
address: {
city: string;
pin: number;
};
} = {
name: "Rahul",
address: {
city: "Delhi",
pin: 110001
}
};
11. Array Type Annotations
Method 1
let numbers: number[] = [1, 2, 3];
Method 2
let names: Array<string> = ["A", "B"];
12. Mixed Type Arrays
let data: (string | number)[] = ["GFG", 100];
This means:
- array can contain strings
- array can contain numbers
13. Tuple Type Annotations
Tuples store fixed types in fixed positions.
let person: [string, number] = ["Rahul", 25];
| Index | Type |
|---|---|
| 0 | string |
| 1 | number |
14. Union Types
Union means “OR”.
Syntax
let value: string | number;
Example
let id: string | number;
id = 101;
id = "EMP101";
15. Literal Types
Restrict values to exact values.
let direction: "left" | "right";
Allowed:
direction = "left";
Not allowed:
direction = "up";
16. Any Type
Disables type checking.
let data: any = 5;
data = "Hello";
data = true;
⚠ Avoid excessive use of any.
17. Unknown Type
Safer alternative to any.
let value: unknown;
You must check type before using it.
if (typeof value === "string") {
console.log(value.toUpperCase());
}
18. Enum Type
Enums store named constants.
enum Role {
Admin,
User,
Guest
}
Usage:
let userRole: Role = Role.Admin;
19. Interface Type Annotations
Interfaces define object structures.
Example
interface User {
name: string;
age: number;
}
Usage:
let user: User = {
name: "Rahul",
age: 22
};
20. Type Alias
Alternative way to define custom types.
type Employee = {
name: string;
salary: number;
};
21. Class Type Annotations
Example
class Car {
brand: string;
price: number;
constructor(brand: string, price: number) {
this.brand = brand;
this.price = price;
}
details(): string {
return `${this.brand} costs ${this.price}`;
}
}
22. Function Type Variables
You can annotate function variables too.
let multiply: (a: number, b: number) => number;
Assign function:
multiply = (x, y) => x * y;
23. Type Assertions
Tell TypeScript the type manually.
let value: unknown = "Hello";
let length = (value as string).length;
24. Never Type
Used when something never happens.
function throwError(): never {
throw new Error("Error");
}
25. Real-World Example
interface Product {
id: number;
name: string;
price: number;
inStock: boolean;
}
const product: Product = {
id: 1,
name: "Laptop",
price: 50000,
inStock: true
};
This is how TypeScript is used in real applications.
26. Advantages of Type Annotations
| Benefit | Explanation |
|---|---|
| Error Detection | Finds mistakes early |
| Better Readability | Easier to understand |
| IDE Support | Autocomplete & hints |
| Safer Refactoring | Easy code changes |
| Large Project Support | Better maintainability |
27. Common Beginner Mistakes
Mistake 1: Using any Everywhere
let data: any;
Avoid unless necessary.
Mistake 2: Wrong Return Types
function add(): string {
return 5; // Error
}
Mistake 3: Incorrect Object Structure
let user: { name: string };
user = {}; // Error
28. Best Practices
✅ Use explicit types in functions
✅ Prefer interfaces for objects
✅ Avoid any
✅ Use union types when needed
✅ Use inference for simple variables
29. Quick Summary Table
| Type | Example |
|---|---|
| string | "Hello" |
| number | 10 |
| boolean | true |
| array | number[] |
| object | {name:string} |
| tuple | [string, number] |
| union | string | number |
| any | any |
| unknown | unknown |
| enum | enum Role {} |
30. Final Understanding
Type annotations are the foundation of TypeScript’s type system.
They help developers:
- write safer code
- reduce runtime bugs
- improve collaboration
- create scalable applications
TypeScript becomes extremely powerful in large applications because type annotations make code predictable and self-documenting.
If you want, I can also teach:
- Advanced Type Annotations
- Interfaces vs Type Aliases
- Generics in TypeScript
- Type Narrowing
- Mapped Types
- Utility Types
- TypeScript Interview Questions
- Complete TypeScript Roadmap