Type assertions tell TypeScript to treat a value as a specific type. Use with caution!
Syntax
Angle Bracket Syntax
let value: any = "hello world";
let strLength: number = (<string>value).length;
Note: Cannot be used in .tsx files (React).
as Syntax (Preferred)
let value: any = "hello world";
let strLength: number = (value as string).length;
Common Use Cases
DOM Manipulation
// TypeScript doesn't know the exact type
let input = document.getElementById("myInput");
// Assert it's an HTMLInputElement
let inputElement = document.getElementById("myInput") as HTMLInputElement;
inputElement.value = "Hello";
// Or with angle brackets
let inputElement2 = <HTMLInputElement>document.getElementById("myInput");
Working with any
let data: any = getDataFromAPI();
// Assert the type you expect
let user = data as User;
console.log(user.name);
Narrowing Union Types
function processValue(value: string | number) {
if (typeof value === "string") {
// TypeScript knows it's string here
console.log(value.toUpperCase());
} else {
// TypeScript knows it's number here
console.log(value.toFixed(2));
}
}
Type Assertions vs Type Guards
Type Assertion (You tell TypeScript)
let value: any = "hello";
let str = value as string; // You're asserting, but no runtime check
Type Guard (TypeScript checks)
function isString(value: any): value is string {
return typeof value === "string";
}
let value: any = "hello";
if (isString(value)) {
// TypeScript knows it's string here
console.log(value.toUpperCase());
}
Double Assertions
Sometimes you need to assert through any first.
let value: string = "hello";
let num = value as any as number; // First to any, then to number
// Use sparingly - usually indicates a design problem
Non-null Assertion Operator
Assert that a value is not null or undefined.
function getElement(id: string): HTMLElement | null {
return document.getElementById(id);
}
let element = getElement("myDiv")!; // Non-null assertion
element.innerHTML = "Hello"; // TypeScript knows it's not null
// Equivalent to:
let element2 = getElement("myDiv") as HTMLElement;
When to Use Type Assertions
✅ Good Use Cases
- DOM manipulation - When you know the element type
- Working with libraries - When types are incomplete
- Migration from JavaScript - Temporary during migration
❌ Avoid When
- You can use type guards instead - More type-safe
- You're not sure of the type - Use
unknownand check - There's a better type-safe solution - Prefer proper typing
Exercises
Exercise 1: DOM Assertions
// Get an element by ID and assert it's an HTMLButtonElement
// Then set its disabled property to true
Exercise 2: Type Guards vs Assertions
// Create a type guard function 'isUser' that checks if a value is a User
// Use it instead of type assertion
Exercise 3: Non-null Assertion
// Create a function that might return null
// Use non-null assertion when you're certain it won't be null
Exercise 4: Working with any
// You have a value of type 'any'
// Assert it as a specific interface type
// Then use its properties safely
Best Practices
- Prefer type guards over assertions - More type-safe
- Use
unknowninstead ofany- Forces type checking - Minimize use of assertions - They bypass type checking
- Document why you're asserting - Add comments explaining
- Consider refactoring - If you need many assertions, types might be wrong
Common Mistakes
- Asserting without checking
// ❌ Dangerous
let value: any = getData();
let user = value as User;
user.name; // Might crash if value isn't actually a User
// ✅ Better
let value: any = getData();
if (isUser(value)) {
value.name; // Safe
}
- Overusing non-null assertion
// ❌ Dangerous
let element = document.getElementById("myDiv")!;
element.innerHTML = "Hello"; // Might crash if element doesn't exist
// ✅ Better
let element = document.getElementById("myDiv");
if (element) {
element.innerHTML = "Hello";
}
- Asserting to wrong type
// ❌ Wrong
let str = "hello";
let num = str as number; // Compiles but wrong!
// ✅ Correct
let str = "hello";
let num = Number(str); // Proper conversion
Next Steps
Learn about Union and Intersection Types.