Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A Promise in TypeScript is a strongly-typed proxy object representing the eventual completion, or failure, of an asynchronous operation. It encapsulates a value that may not be available yet, enforcing compile-time type safety on the resolved value through generics (Promise<T>).

Type Signature and Generics

TypeScript defines a Promise using a generic type parameter T, which dictates the exact compile-time type of the value the Promise will yield upon successful execution.
const numericPromise: Promise<number> = new Promise((resolve, reject) => {
    resolve(42); // Valid
    // resolve("42"); // Type Error: Argument of type 'string' is not assignable to parameter of type 'number'
});

The Executor Function

The Promise constructor accepts an executor callback. TypeScript strictly types the arguments of this executor: resolve and reject.
  • resolve: A function that accepts a value of type T or a PromiseLike<T>.
  • reject: A function that accepts a reason, typically typed as any or unknown.
The constructor signature is defined within the TypeScript standard library as follows:
interface PromiseConstructor {
    new <T>(executor: (
        resolve: (value: T | PromiseLike<T>) => void, 
        reject: (reason?: any) => void
    ) => void): Promise<T>;
}

State Machine

A Promise exists in one of three mutually exclusive runtime states. While these state transitions occur entirely at runtime, TypeScript’s compile-time type system tracks the type of the value yielded upon fulfillment via the generic parameter T:
  1. Pending: The initial state. No value is available.
  2. Fulfilled: The operation completed successfully. The Promise yields a value of type T.
  3. Rejected: The operation failed. The Promise yields a rejection reason (typically Error or unknown).

Instance Methods and Type Propagation

When chaining Promises, TypeScript infers the return type of the subsequent Promise based on the return value of the callback provided to .then() or .catch().
declare const initialPromise: Promise<number>;

// Type propagation: Promise<number> -> Promise<string> -> Promise<boolean>
const chainedPromise: Promise<boolean> = initialPromise
    .then((val: number) => val.toString()) 
    .then((str: string) => str.length > 0)
    .catch((err: unknown) => false); 
If a .then() callback returns a non-Promise value of type U, TypeScript automatically wraps the return type as Promise<U>. If it returns a Promise<U>, the resulting type is flattened to Promise<U>, preventing nested types like Promise<Promise<U>>.

Static Methods and Tuple Inference

TypeScript provides advanced type inference for Promise static methods, particularly when handling arrays or iterables of Promises. Promise.all When passed a tuple of Promises, Promise.all infers a Promise resolving to a tuple of the exact corresponding types.
const p1 = Promise.resolve(100);       // Promise<number>
const p2 = Promise.resolve("Active");  // Promise<string>

// Inferred type: Promise<[number, string]>
const combined = Promise.all([p1, p2]); 
Promise.race Returns a Promise that resolves or rejects as soon as the first Promise in the iterable settles. The return type is a union of the generic types of the input Promises.
// Inferred type: Promise<number | string>
const raced = Promise.race([p1, p2]);

Async/Await Return Types

The async modifier in TypeScript acts as a syntactic guarantee that a function will return a Promise. If the function’s body returns a raw value of type T, the TypeScript compiler enforces the function signature as Promise<T>.
// The return type MUST be Promise<string>, even though a raw string is returned.
async function getStatus(): Promise<string> {
    return "OK"; 
}

// Awaiting unwraps the Promise<T> back to T
async function evaluateStatus(): Promise<void> {
    const status: string = await getStatus(); 
}

The PromiseLike<T> Interface

TypeScript utilizes structural typing (duck typing) for asynchronous objects via the PromiseLike<T> interface. An object is considered PromiseLike (often called a “Thenable”) if it implements a .then() method, even if it is not an instance of the native Promise class. TypeScript allows await to be used on any PromiseLike<T> object, safely unwrapping it to type T.
interface PromiseLike<T> {
    then<TResult1 = T, TResult2 = never>(
        onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
        onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
    ): PromiseLike<TResult1 | TResult2>;
}
Master TypeScript with Deep Grasping Methodology!Learn More