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

  1. DOM manipulation - When you know the element type
  2. Working with libraries - When types are incomplete
  3. Migration from JavaScript - Temporary during migration

❌ Avoid When

  1. You can use type guards instead - More type-safe
  2. You're not sure of the type - Use unknown and check
  3. 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

  1. Prefer type guards over assertions - More type-safe
  2. Use unknown instead of any - Forces type checking
  3. Minimize use of assertions - They bypass type checking
  4. Document why you're asserting - Add comments explaining
  5. Consider refactoring - If you need many assertions, types might be wrong

Common Mistakes

  1. 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
}
  1. 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";
}
  1. 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.