TypeScript in the Age of AI

4 hours, 28 minutes CC
TypeScript in the Age of AI

Course Description

Master TypeScript and get better results from AI generated code. Explore advanced techniques like generics, conditional types, and discriminated unions, while gaining the skills to spot subtle mistakes and craft better prompts. Become the TypeScript expert on your team and take ownership over your type system.

Prerequisite: Solid understanding of TypeScript or our TypeScript Fundamentals course.
Preview

Course Details

Published: July 30, 2026

Learn Straight from the Experts Who Shape the Modern Web

Your Path to Senior Developer and Beyond
  • 300+ In-depth courses
  • 24 Learning Paths
  • Industry Leading Experts
  • Live Interactive Workshops

Table of Contents

Introduction

Section Duration: 4 minutes
  • Introduction
    Adam Rackis introduces the course by explaining why TypeScript's foundational role makes it uniquely risky to get wrong when generating code with AI. He previews the workshop's dive into core features like generics and mapped types, which will help viewers prompt AI more effectively and catch its mistakes.

TypeScript Basics

Section Duration: 48 minutes
  • Nominal vs Structural Typing
    Adam explains the difference between structural typing and nominal typing, emphasizing that in structural typing, types define the structure that valid values will hold rather than just the valid variables a value can be. He also delves into the concept of types as sets of valid values, using examples like literal values and unions to illustrate how types can be defined.
  • TypeScript Basics
    Adam covers the basics of TypeScript, including type inference, the any type, unknown type, and never type. He also explains how to type functions, use unions, and create types for literal values like true and false.
  • typeof Operator
    Adam covers a variety of real-world practical tips and tricks in TypeScript, emphasizing the use of the type of operator to extract static types from runtime values efficiently. He then explores the importance of relying on inferred typing in functions, showcasing how TypeScript can accurately infer types without the need for manual declaration in most cases.
  • Type-Safe Forms
    Adam demonstrates how to use TanStack form, explaining the process of setting default values and utilizing the use form hook to create a form variable with statically typed properties like field components. He then guides students through a technique to simplify complex form types by using a two-step process involving TypeScript utility types like return type, enabling static checking and efficient code organization.
  • Exporting Types for Public APIs
    Adam explains the importance of exporting types when creating public APIs, emphasizing the need to export types for both function parameters and return types. He demonstrates how to use TypeScript utility types like `return type` and `parameters` to extract necessary types from functions, enabling proper typing without manual intervention.
  • Return Types
    Adam walks through the concept of conditional return types in TypeScript functions, explaining how TypeScript infers union types for conditional return values and how to explicitly declare return types to enforce specific contracts. He then demonstrates a two-step process using a custom lookup object to ensure an array contains unique keys from a given type, showcasing how TypeScript can enforce type safety throughout the process.

Generics

Section Duration: 48 minutes
  • Generics
    Adam explores the concept of generics, comparing them to template systems in languages like C++. He breaks down how generics allow passing types as parameters, demonstrating the flexibility they offer for working with various data types, including built-in and user-defined types.
  • Generics in React Components
    Adam explains how to properly handle generics in React components, demonstrating the importance of adding a generic type to the component and utilizing parentheses and a comma to avoid syntax clashes with JSX. He then outlines two approaches to typing the component, either manually typing the props or using the built-in type `FC` for a fully typed component.
  • Use Case: Grabbing Arguments
    Adam explores the concept of generics, demonstrating how they can be used to maintain specificity in TypeScript by adding a generic argument to a method. He breaks down the process of using a generic constraint to ensure that the type parameter is limited to a specific type, such as a catalog item, preventing unintended data types from being accepted.
  • Use Case: Custom Proxying Layer
    Adam explains how to ensure that various functions in a codebase take the same arguments by creating a loader function that enforces argument consistency. He demonstrates using TypeScript tricks like 'as const' and spreading to infer specific tuple types, ensuring type safety without burdening other engineers with intricate details.
  • Zustand with Generics
    Adam demonstrates how to use Zustand for state management in React, showing how to create a store with initial values and selectors to access specific state slices. He explains the importance of manually adding generics to ensure correct type inference when using custom selectors in Zustand.
  • Generics Exercise
    Adam demonstrates how to enhance a groupBy function by introducing generics to ensure more precise typing. He guides students through enforcing valid key names using key of T, resulting in a record of string values for each city and an array of users for each city.
  • Generate Generics with AI
    Adam demonstrates how understanding TypeScript features, like generics and inferred typings, can streamline code changes and make AI integration easier in software engineering tasks. He explores leveraging AI to refactor code by asking for specific constraints and type inferences, showcasing the benefits of knowing how to interact effectively with AI tools in development workflows.

Unions

Section Duration: 53 minutes
  • Unions
    Adam Rackis explores TypeScript unions in depth, from narrowing and intersections to why enums should be avoided in favor of string literal unions. He then demonstrates discriminated unions through a cat-and-dog example, contrasting the fragile "in" operator with proper discriminator properties, and shows how this knowledge lets you prompt AI to refactor a union correctly in seconds.
  • Type Narrowing
    Adam Rackis walks through more type narrowing techniques that TypeScript recognizes from native JavaScript, including typeof for built-in types and instanceof for class instances. He closes with a practical example using Array.isArray to narrow between a single item and an array of items.
  • Type Guards
    Adam demonstrates how to create custom type guards in TypeScript to manually narrow types within a union, using functions like 'animal is lion' and 'animal is cat' to check and narrow down specific types based on conditions. He then explores the use of type guards in array methods like filter to ensure type safety and how TypeScript's type inference can simplify the process by recognizing type guards like 'x is number' for filtering arrays.
  • Type Narrowing to Never
    Adam demonstrates how to enforce exhaustive type checking in TypeScript by narrowing down unions until only 'never' is left, ensuring every possible type is covered. He shows a clever trick of using an 'assert never' function to force coverage of all possibilities, preventing errors when adding new types to the union.
  • Excess Property Checks
    Adam explores excess property checking in TypeScript, demonstrating how assigning object literals to typed variables triggers errors when extra properties are present, showcasing the use of the satisfies keyword to enforce strict type structure without allowing wider types to be inferred. He guides students through understanding how this feature works and its practical application in maintaining type integrity.

Conditional Types

Section Duration: 51 minutes
  • Conditional Types & Inferring
    Adam explores conditional types in TypeScript, demonstrating how to create basic conditional types using ternary operators to return different types based on conditions. He then delves into more complex examples, showcasing how to use the infer keyword to extract specific types from generic arguments, enforcing constraints to ensure that certain types are passed into the conditional types.
  • Generating Conditional Types with AI
    Adam demonstrates how to work with AI models to generate types for React components based on specific conditions, showing examples of prompts and results obtained. He then explores the importance of understanding and guiding the output towards simpler solutions, emphasizing the need to comprehend generated types for future use.
  • Conditional Types Exercise
    Adam demonstrates how to implement custom conditional types in TypeScript, starting with creating a get return type that mimics the behavior of built-in return types. He then guides students through creating a get parameters type, ensuring it only works with functions and comparing the custom types to TypeScript's built-in versions.
  • Using Unions with Conditional Types
    Adam demonstrates how passing a union to a conditional type in TypeScript results in the conditional type running with each member of the union and then unioning all those results together. He breaks down how the conditional type kicks out any nevers it encounters along the way, providing a clear understanding of how the process works graphically and through code examples.
  • Validating Types Match
    Adam demonstrates how to write type assertions for unit testing complex types in TypeScript, emphasizing the simplicity of using type assertions over testing frameworks like Jest or Vtest. He explores creating type helpers to verify if two types match, utilizing conditional types to achieve the desired behavior and avoid union type issues.
  • Tuple Types
    Adam walks through the process of implementing a type in TypeScript that checks if one tuple type is a subset of another, explaining the algorithm using a Pac-Man analogy to compare and process tuple members recursively. He demonstrates how to split tuple types, infer their heads and the rest of the items, and recursively call the function to check for type matching, emphasizing the importance of syntax and type extensions in TypeScript.
  • Finding the Longer Subset
    Adam explores the concept of managing argument lists in prefetch and load calls, emphasizing the importance of passing the longer list of arguments to a single load method. He demonstrates how to determine which argument list is longer and ensure they are subsets of each other to handle different scenarios effectively.

Advanced Techniques

Section Duration: 54 minutes
  • Function Overloading
    Adam explains the concept of function overloading, showcasing how to create multiple versions of a function based on the types of their parameters. He contrasts using conditional types versus function overloads in TypeScript, demonstrating how function overloads provide distinct APIs without the confusion of unions.
  • Template Literal Types
    Adam explores the concept of template literal types, demonstrating how to interpolate values and types inside a template literal type, allowing for autocomplete based on the values interpolated from a union. He then breaks down how to manipulate literal string types, filter them, and use them in functions, showcasing the niche yet powerful capabilities of template literal types in TypeScript.
  • Variance
    Adam explains the concept of variance, covering covariance and contravariance in types, showcasing how providing more specific or less specific types than what is asked for can impact variables, function arguments, and return types. He demonstrates how this understanding is crucial when working with function types, particularly in scenarios like React event handlers, where treating a more specific event type as a generic one can be valid and useful.
  • Mapped Types Overview
    Adam demonstrates how TypeScript’s map types enable helpful type transformations, including filtering unions, remapping keys with template literals, converting object properties, and projecting values into unions.
  • Using Mapped Types
    Adam demonstrates how to strip functions and return types from an API object using TypeScript utility types like `return type` and `Omit`. He then explores filtering out specific properties based on function return types, cautioning against incorrect assumptions due to TypeScript's variance in return types.
  • Mapped Types Exercise
    Adam guides students through implementing a map type that converts date properties to strings while keeping other types unchanged. He also expands on the example by generating a similar solution from an agent to highlight the importance of understanding what's beging generated.
  • Constraining Keys Exercise
    Adam demonstrates how to create a helper type for string or number keys, looping through keys and filtering out invalid ones to ensure only valid keys are allowed for grouping. He then refines the group by type, excluding certain keys like 'hobbies' and ensuring TypeScript compatibility by casting as string or number where needed.

Wrapping Up

Section Duration: 5 minutes
  • Wrapping Up
    Adam wraps up the course by walking through an advanced mapped type exercise that filters and renames object keys using template literal types and conditional infer clauses. He uses an unexpected result along the way to reinforce a key lesson: even when TypeScript can handle deeply nested logic, it's worth stepping back for a simpler solution.

Earn a Completion Certificate

After completing this course, you'll receive a certificate of completion that serves as proof of your achievement, showcasing your expertise, and commitment to professional development. You can easily share this certificate on your LinkedIn profile to highlight your new skills and demonstrate continuous learning to potential employers and professional connections.

Sample completion certificate