Execute Program

TypeScript Basics: Generic Function Inference

Welcome to the Generic Function Inference lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • Generics would be tedious if we always had to write them out. Fortunately, they can be inferred when calling generic functions.

  • >
    function length<T>(elements: T[]): number {
    return elements.length;
    }
  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    length([]);
    Result:
    0Pass Icon
  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    length([1, 2]);
    Result:
    2Pass Icon
  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    [
    length([1, 2]),
    length(['a']),
    ];
    Result:
    [2, 1]Pass Icon
  • We called the function twice without specifying the type parameters. We could've written length<number>(...) and length<string>(...). But it's much nicer to read the code without them!

  • How does the compiler do this while preserving type safety?

    • We call length([1, 2]).
    • The compiler sees that length<T> takes an Array<T>.
    • The compiler also sees that [1, 2] is an Array<number>.
    • We passed an Array<number> for the Array<T>, so T must be number.

    Then the whole process repeats for the length(['a']) call. In that case, T is string.

  • The two calls to length are checked separately. It's fine that T is number for the first call and string for the second. That's the purpose of generics: to allow us to reuse code in different ways.

  • Type safety is maintained throughout all of this. Remember: inference doesn't eliminate type safety!

  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    const s: string = length([1]);
    Result:
    type error: Type 'number' is not assignable to type 'string'.Pass Icon