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 TypeScript generic method is a function defined within a class, interface, or object literal that declares one or more type parameters. These type parameters act as placeholders for concrete types, allowing the method’s parameter types, return type, and local variables to be strictly typed based on the specific invocation context, independent of any class-level type parameters.

Syntax and Declaration

Type parameters are declared inside angle brackets (< >) immediately preceding the method’s parameter list. This establishes a lexical scope for the type parameter that is restricted entirely to the method itself.
class DataProcessor {
    // T and U are method-level type parameters
    process<T, U>(input: T, metadata: U): [T, U] {
        return [input, metadata];
    }
}

Type Resolution and Inference

When a generic method is invoked, the TypeScript compiler resolves the type parameters through one of two mechanisms:
  1. Explicit Type Arguments: The developer explicitly defines the types during invocation.
  2. Type Inference: The compiler infers the types based on the runtime arguments passed to the method.
const processor = new DataProcessor();

// 1. Explicit Type Arguments
processor.process<string, number>("value", 42);

// 2. Type Inference (T inferred as boolean, U inferred as string)
processor.process(true, "active"); 

Type Constraints

Generic methods can enforce structural contracts on type parameters using the extends keyword. This restricts the set of permissible types to those that satisfy the specified interface, class, or primitive type, allowing the method to safely access properties guaranteed by the constraint.
interface HasLength {
    length: number;
}

class Metrics {
    // T is constrained to types that possess a 'length' property of type number
    measure<T extends HasLength>(item: T): number {
        return item.length; 
    }
}

Default Type Parameters

Type parameters in generic methods can be assigned default types using the = operator. This is necessary when a type parameter cannot be inferred from the required arguments (e.g., when it is only used as a return type). If the compiler cannot infer the type from the invocation context and no explicit type argument is provided, it will fall back to the default type.
class Parser {
    // T cannot be inferred from the 'jsonString' argument.
    // It defaults to 'any' if no explicit type argument is provided.
    parse<T = any>(jsonString: string): T {
        return JSON.parse(jsonString);
    }
}

const parser = new Parser();

// Explicitly provides the type argument; T becomes { id: number }
const typedData = parser.parse<{ id: number }>('{"id": 1}');

// No explicit type argument provided; T falls back to the default 'any'
const untypedData = parser.parse('{"id": 1}');

Interplay with Class Generics

A generic method can exist within a generic class. Method-level type parameters can shadow class-level type parameters if they share the same identifier, though this is generally considered an anti-pattern due to reduced readability.
class Container<T> {
    private value: T;

    constructor(val: T) {
        this.value = val;
    }

    // Method uses class-level generic 'T' and introduces method-level generic 'U'
    transform<U>(transformer: (val: T) => U): U {
        return transformer(this.value);
    }

    // Shadowing: Method-level 'T' overrides class-level 'T' within this scope
    shadow<T>(newValue: T): T {
        return newValue;
    }
}
Master TypeScript with Deep Grasping Methodology!Learn More