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

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

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:

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

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

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:

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:

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:

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:

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, tryCastreturnsundefinedwhen the type‑guard returns false. This allows you to handle optional values gracefully by checking forundefined` 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →