# How to Use TypeScript Cast to Type: A Complete Guide to the `cast` Utility

> Learn TypeScript cast to type for runtime validation. This guide explains how cast combines values with type guards to catch errors unlike compile-time assertions.

- Repository: [Microsoft/TypeScript](https://github.com/microsoft/typescript)
- Tags: how-to-guide
- Published: 2026-02-16

---

**The TypeScript `cast` function provides runtime type validation by combining a value with a type-guard function, throwing an error if the check fails, unlike compile-time-only type assertions.**

TypeScript adds a static type system to JavaScript, but at runtime all type information is erased. When you need to safely convert an unknown value to a specific type, the TypeScript compiler source code itself provides a robust `cast` utility that validates types at runtime using type guards.

## What Is Type Casting in TypeScript?

Type casting in TypeScript refers to the process of treating a value as a specific type, either at compile time or runtime. Because TypeScript compiles to plain JavaScript, which has no runtime type information, the language provides two distinct mechanisms: **type assertions** that tell the compiler to trust your judgment, and **runtime casting** that actively validates values using type-guard functions.

## TypeScript Cast to Type: The `cast` Utility Explained

The TypeScript compiler implements a generic `cast` function that performs safe runtime type narrowing. Unlike the `as` keyword, which disappears after compilation, `cast` executes a validation function and throws if the value does not match the expected shape.

### Core Implementation in [`src/compiler/core.ts`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/core.ts)

The `cast` function is defined in **src/compiler/core.ts** (lines 1783‑1886). It accepts a value that may be `undefined` and a type‑guard predicate, returning the value with the narrowed type or throwing a debug error:

```typescript
export function cast<TOut extends TIn, TIn = any>(
    value: TIn | undefined,
    test: (value: TIn) => value is TOut
): TOut {
    if (value !== undefined && test(value)) return value;
    return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`);
}

```

### Export via [`src/services/utilities.ts`](https://github.com/microsoft/TypeScript/blob/main/src/services/utilities.ts)

To make the utility available throughout the compiler and language services, `cast` is re‑exported from **src/services/utilities.ts** (line 16):

```typescript
import { cast } from "./utilities";

```

This centralized export allows refactoring tools and compiler internals to import the function consistently.

## How to Use `cast` in Your Projects

While `cast` originated in the TypeScript compiler, the pattern applies to any TypeScript codebase that needs runtime validation. You can implement the same utility or use the compiler’s exported version if building language service plugins.

### Basic Runtime Casting with Type Guards

First, define a type guard that validates the shape of your data:

```typescript
interface User {
    id: number;
    name: string;
}

function isUser(obj: any): obj is User {
    return typeof obj?.id === "number" && typeof obj?.name === "string";
}

```

Then use `cast` to safely convert an unknown value:

```typescript
import { cast } from "typescript/lib/services/utilities"; // or your own implementation

const raw = JSON.parse('{"id":42,"name":"Alice"}');
const user = cast(raw, isUser); // Type is User; throws if validation fails
console.log(user.name);

```

### Handling Optional Values with `tryCast`

When a value might legitimately be `undefined` or the wrong type, use `tryCast` (also defined in **src/compiler/core.ts**) which returns `undefined` instead of throwing:

```typescript
const maybeUser = tryCast(raw, isUser);
if (maybeUser) {
    // maybeUser is typed as User here
    console.log(maybeUser.id);
}

```

### Real-World Example: AST Node Narrowing

The TypeScript compiler uses `cast` extensively when refactoring code. For example, in **src/services/refactors/inlineVariable.ts** (line 197), the code safely narrows an AST node to a `VariableStatement`:

```typescript
const variableStatement = cast(declaration.parent.parent, isVariableStatement);

```

This pattern ensures that refactoring operations only proceed when the AST structure matches the expected shape, preventing runtime errors during code transformations.

## Type Assertions vs. Runtime Casting

Understanding when to use compile‑time assertions versus runtime casting is crucial for type safety.

| Approach | Syntax | Runtime Effect | Best For |
|----------|--------|----------------|----------|
| **Type Assertion** | `value as Type` or `<Type>value` | None – erased during compilation | Quickly informing the compiler of a more specific type when you are certain of the value’s shape (e.g., DOM elements). |
| **Runtime Cast** | `cast(value, typeGuard)` | Executes validation function; throws on failure | Safely narrowing values from external sources (APIs, `JSON.parse`, user input) where the type is uncertain at compile time. |

Use type assertions for compiler assistance only. Use `cast` when you need runtime guarantees that the value matches the expected TypeScript type.

## Summary

- **TypeScript cast to type** functionality encompasses both compile‑time assertions and runtime validation utilities.
- The `cast` function in **src/compiler/core.ts** provides safe runtime narrowing by accepting a value and a type‑guard predicate, throwing a debug error if validation fails.
- For optional values, `tryCast` returns `undefined` instead of throwing, offering a non‑fatal alternative.
- The TypeScript compiler uses these utilities internally—such as in **src/services/refactors/inlineVariable.ts**—to safely manipulate AST nodes during refactoring.
- Choose **type assertions** (`as T`) for compile‑time hints and **runtime casting** (`cast`) when validating external data.

## Frequently Asked Questions

### What is the difference between `as` and `cast` in TypeScript?

The `as` keyword performs a **type assertion**, which is a compile‑time only instruction that tells the TypeScript compiler to treat a value as a specific type without any runtime validation. In contrast, the `cast` utility function—defined in **src/compiler/core.ts**—performs **runtime validation** by executing a type‑guard function and throwing an error if the value does not match the expected type.

### Where is the `cast` function defined in the TypeScript source code?

The `cast` function is implemented in **src/compiler/core.ts** (lines 1783‑1886) and re‑exported from **src/services/utilities.ts** (line 16) for use throughout the compiler and language services. This location makes it available to refactoring tools, code fixes, and other compiler internals that need safe runtime type narrowing.

### How do I handle casting that might fail without throwing an error?

Use the `tryCast` utility, which is also defined in **src/compiler/core.ts`. Unlike `cast`, which throws a debug error on validation failure, `tryCast` returns `undefined` when the type‑guard returns false. This allows you to handle optional values gracefully by checking for `undefined` before proceeding with type‑specific operations.

### Can I use `cast` with generic type guards?

Yes, the `cast` function is fully generic and designed to work with type‑guard predicates. Its signature—`cast<TOut extends TIn, TIn = any>(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut`—allows you to pass any type‑guard function that uses the `value is Type` return type annotation, making it compatible with complex generic constraints and union type narrowing.