
Explore a fundamentals-first approach to advanced TypeScript, mastering core type system concepts—from template literal types to union and map types—through hands-on exercises.
Explore the real-world applicability of advanced TypeScript concepts through framework choices and front-end versus back-end considerations. Read GitHub TypeScript codebases to gain practical aha moments and prepare for React applications.
Set up an advanced TypeScript project with the default config and target 2020, using ES6 and DOM libraries; access codes for each lesson in the first video and on GitHub.
Explore TypeScript's primitive types, literal types, and how the language treats data as types, with examples of strings, numbers, booleans, and type-safe assignments.
Explore literal types in TypeScript, where exact values become types and restrict variables to a single value or a limited set of values.
Explore union and intersection types in TypeScript to model notification methods like email, SMS, or push, and preview how conditional types will transform union branches.
Explore how the unknown type sits at the top of TypeScript's type hierarchy, and learn how intersections and unions determine narrowest or widest branches for assignability.
Discover the never type as the bottom of TypeScript's type hierarchy, and how intersecting incompatible types yields never. Understand unknown's position and how assignability runs bottom-to-top.
Avoid the any type; it erodes type safety and autocompletion by existing everywhere. Use it when required, and apply it in a contaminated way to prevent leakage to external libraries.
Explore TypeScript's built-in data representations: object types, record types, tuple types, and array types, and see how fixed properties, unknown keys, fixed-length tuples, and homogeneous arrays shape data.
Apply type checking in TypeScript basics by ensuring a set of emails accepts only strings, using a type parameter or explicit string-set annotation.
Practice #2 demonstrates enforcing a books map with numeric keys and a book object value (title, author, price), using type parameters to ensure correct key and value types.
Learn how to type json.parse results in TypeScript by replacing any with a concrete order details type, extracting the type from any and applying it to ensure correct data shapes.
Typing an async fetch server version function to return a number, this practice teaches that the function signature should be Promise<number> since await resolves a number from a promise.
Enforce theme constraints by typing the theme argument as a union of 'light' and 'dark', ensuring the apply theme function accepts only these literals and fails otherwise.
Explore typing a get by index function in TypeScript, using generics and type parameters to return either the first or second argument based on a numeric index, with tests passing.
Explore a production-grade TypeScript pattern for building a response object by composing two generic objects through an intersection, returning a type that merges base and data properties.
Practice #8 demonstrates defining an accumulator as a callable function with a reset method, using intersection types to attach reset. It shows a number-to-number function signature with reset returning void.
explore a typescript function that extracts an error code from either a custom error instance or a plain object, returning string or number with an unknown fallback.
Learn how assert unreachable and exhaustiveness checks use never as the argument and return type to flag unreachable or unhandled API status branches (200, 404, 500) in TypeScript.
Learn how to type this inside a normal function, distinguish this from parameters, and compare how arrow functions bind this in classes versus objects, with lat and LNG as examples.
Learn how to define and instantiate a class in TypeScript, initialize lat and lng via a constructor, and enforce read-only properties for safer type checking.
Define a relocate method in a class to accept lat and LNG and update them with this; use an arrow function for binding or a regular method for legacy code.
Receive default coordinates by passing an optional location object with lat and lng numbers into the constructor, falling back to zero when none is provided, with TypeScript inferring types.
Learn how to declare a getter in a TypeScript class to expose a map pin's coordinates as a lat and LNG object, using the get keyword to access without parentheses.
Learn how to enforce private properties in a TypeScript class using the private keyword or the # syntax to restrict outside access while exposing safe getters.
Explore setter methods in TypeScript by using a coordinates property with a getter and a setter, showing automatic switching between reading and writing and type inference.
Explore inheritance in TypeScript by extending a coordinates class with a map pin, separating math and UI concerns, and using super to pass lat and lng for concise class design.
Learn how TypeScript models data with objects and records, define object types like an account with username, balance, and verified, and explore subtyping, never, and unknown.
Learn how TypeScript enforces excess property checks on inline object literals, aligning them with a type’s minimum properties, while pre-created objects with extras are allowed.
Extract the type of an object property in TypeScript with square brackets, then form a union of keys like username or experience to combine types at the type level.
Explore how the key of operator creates a union of object keys with keyof and uses indexing to derive value types, such as string and boolean, from a profile type.
Declare optional properties in TypeScript with the question mark syntax, letting keys be omitted. See why this beats union with undefined for cleaner object types.
Combine object types using the intersection operator to build modular, reusable TypeScript profiles, merging identity, personal info, and permission into a full user profile or simpler variants.
Combine object types by using interfaces to build modular types, transforming intersections into extends to create base types like id and post, and composing articles and feedback with multiple extends.
Explore how combining object types in TypeScript with intersections or unions affects keys, including the keyof operator.
Explore how intersections merge object types, causing never for overlapping properties like phone or ISBN, and see why interfaces offer clearer errors and better type checking.
Learn how record types enforce a value type across all keys, boolean values included, use the built-in record helper, and restrict keys with string literal unions to extract value types.
Master TypeScript helper functions that modify and extract object types, including partial, required, pick, and emit, to build flexible, production-grade type definitions.
Define a store inventory type in TypeScript that maps product names to quantities using a Record type; explore manual and Record helper approaches to enforce string keys and number values.
Type the forecast to accept only the four region keys north, south, east, and west using a union with a record; ensure properties are numeric and restrict extra keys.
Extract a subobject type from a blog post data structure using TypeScript's pick helper, keeping the original data untouched while exposing only title and content.
Practice #4 demonstrates using TypeScript's Partial helper to make blog post fields optional, enabling update post to accept any subset of properties like title, content, author, and published at.
Learn to make the timestamp property optional in a type T that has a timestamp, using pick, omit, partial, and intersection in TypeScript.
Master the update settings type by merging a base with overrides, using keys of overrides to emit only unique properties, and intersecting with the overrides to ensure all tests pass.
Explore TypeScript tuples and arrays with fixed-length, distinct types and indexed access. Learn number literal types, unions, extracting element types, optional elements, and the spread operator for concatenating tuples.
Understand how TypeScript arrays enforce a single element type, include union options, and are declared with square brackets or array<...>, with insights on records and element type via indices.
Learn how variadic tuples let you mix tuples with arrays to enforce patterns, starting with five or ending with a period, or codes starting with a or b.
Define a single tuple type for function parameters using variadic tuples with named and optional elements and rest parameters, covering username, optional age, and addresses.
Make arrays safer in TypeScript by using read only string arrays to prevent mutation in a log messages function. It prevents mutating the array via push or index access.
Learn how to make tuples safer in TypeScript by using the read only keyword to prevent mutation when passing immutable tuples to functions that mutate data.
Learn to compute a tuple’s length in TypeScript, handle dynamic tuples, and derive next index with a type helper using spread operator to append an element, producing length plus one.
Practice #1: implement a get first element type that extracts the first element from a tuple, returning undefined for empty tuples, then use the index type to access position zero.
Demonstrates building a generic tuple type that appends an element to the end using the rest operator, producing a new tuple and passing all test cases.
Practice #3 composes two tuples into a single tuple using the rest operator for the second input, emphasizing how argument order affects test cases passing.
Learn to create a TypeScript type guard for type narrowing and non-empty arrays. Use a generic [T, ...T[]] tuple with a spread operator to ensure safe, non-empty inputs.
Explore conditional types and branching in TypeScript, using the one-line conditional expression with ? and : to select between types. Understand how type logic mirrors the ternary operator.
Understand how the extends operator powers TypeScript conditional types by checking assignability in A extends B, yielding true or false branches and enabling an if-like generic type via constraints.
Learn how to constrain generic type parameters in TypeScript using the extends keyword to gate accepted types from a set, preserve literal types, and enforce non-empty tuples.
Master conditional types in TypeScript by replacing nested ternaries with an object type indexed by a constrained union, selecting status names like loading, success, or rejected, with unknown as default.
Explore conditional types in TypeScript and their pattern matching of type shapes. Test products with string titles and number prices, nested account details with currency, and tuple-based plan rules.
Discover how the infer keyword enables type inference in TypeScript by pattern matching against objects, extracting property types, including nested properties, and comparing it to destructuring.
Explore how the infer keyword enables pattern matching on tuples to extract the first element, the rest, or both the first and last elements, using TypeScript conditional types.
Explore how TypeScript function types work as structured types that expose parameter tuples and return types, capturing them with infer in conditional types.
Explore how the infer keyword extends beyond built-in types to deduce inner types from your own generic types, with sets, containers, and pairs as examples.
Learn how to simulate block scoped variables in TypeScript using the infer keyword in conditional types, capturing a heavy computation result to reuse it and avoid recomputation.
Practice solving a TypeScript challenge using a generic t and a conditional type that extends a two-element tuple pattern, via pattern matching, returning true or false.
Practice conditional types and tuple pattern matching to select editable or basic notes by user plan and role in a real-world fetch node.
Practice using the getproperty fallback utility to type config values, returning the property's type or a fallback when it doesn't exist. Use as const for literal, read-only types.
Extract the data property type from a generic type T with a conditional check, returning undefined if data is missing and infer the data type when present.
Learn how a conditional type extracts the payload type from an API response by inferring P and returning the payload type, or the input type otherwise, with tests.
Explore a TypeScript type utility that removes the first element from a steps tuple, yielding the remaining steps or an empty tuple, using infer and the rest operator.
Explore a conditional type that uses infer to pattern-match and extract the opening and closing prices from a price tuple, returning [open, close] for two or more elements.
Practice #8 uses conditional types to decide if an order can be placed by checking logged in and valid payment, comparing nested conditionals with tuple pattern matching for readability.
Explore a practical TypeScript utility that extracts a union of element types from arrays, handling no nesting, a single level of nesting, or deeper nesting by inferring inner element types.
Explore how TypeScript uses recursion in the type system to repeat operations, embracing a functional paradigm over loops, with tuples, conditional types, generics, and base cases.
Explore looping over tuple types in TypeScript via recursion, splitting a table into head and tail, then processing the head before recursing on the tail to implement a find column.
Learn to map over a tuple in TypeScript using a recursive type, extracting each element's role from objects to produce a new tuple of roles.
apply the type script filter pattern to a tuple by recursively extracting string elements, building a filter strings type, and using conditional types to retain only strings.
Apply the reducer method in TypeScript by reducing a tuple to an object, using an accumulator, transformation rule, and recursive splitting of head and tail.
Master inferring constraints in advanced type functions with production-grade TypeScript, using array-based input constraints and recursion to safely extract title types from profiles via infer and conditional types.
Learn type-level programming by building a generic compose config that reduces a tuple of configuration objects into a single intersection type, using an accumulator and recursive reduce.
Type a tuple of promises in TypeScript using gatherAsync and extractResults to return a promise of a tuple of their resolved values, achieved via recursion.
Practice #3 demonstrates writing a recursive TypeScript utility that filters a tuple of sensor configurations by allowed types, returning only readings whose type matches the union of allowed types.
Explore the sync readings utility type that turns a tuple of sensor readings into a single typed tuple, using recursion and first-tuple inference to combine values.
Practice #5 demonstrates a filter by type utility that filters a tuple to include only elements assignable to a target type, using extends, conditional checks, and recursive calls.
Explore template literal types in TypeScript to form new string types by combining city, country, and other literals, including numbers and booleans for dynamic file labels and keys.
Embed primitive types into template literal types to build string patterns in TypeScript, using literals, numbers, booleans, and years to enforce formats, while noting symbols cannot be converted to strings.
Explore TypeScript template literal types to generate union string patterns from unions, using examples with size and theme options, and apply distributivity, as const, and exhaustive switch patterns.
Explore building type-safe endpoints with template literals by combining lower case actions and capitalized targets, and enforce structure with the satisfies keyword and a record of endpoint functions.
Learn template literal types and infer in TypeScript to extract string parts, such as splitting a name into first and last, or parsing versions like 1.2.3 into major, minor, patch.
Learn advanced TypeScript patterns to split a string at the first space or first character, using infer to derive the first part and the remainder, with left-to-right pattern logic.
Explore how to use TypeScript template literal types and conditional types with recursion to extract the final word and to split a full name into first and last names.
Explore converting snake_case to camelcase with template literals, conditional types, and recursion, using a helper to keep the first word untouched while capitalizing subsequent segments.
Practice #1 helps you define a template literal pattern that enforces an api key starting with key followed by a space, then a three-dash four-segment key, validating types in TypeScript.
Practice #2 guides implementing a TypeScript conditional type that returns true when input string is in all lowercase by comparing it to the lower case helper function, with no recursion.
Apply a production-grade TypeScript technique by validating generic string patterns with template literals and backticks to determine if a string ends with a fixed suffix, returning true or false accordingly.
Practice #4 implements a recursive type that removes vowels from a string by processing each character, skipping vowels, and accumulating non-vowels; then lowers the result with a helper.
Explore a TypeScript utility that recursively extracts placeholders from a command template, splitting on two special characters and building an intersection of objects mapping each placeholder to a string.
Practice #6 guides you to implement separate and combine TypeScript types to split and join strings by a separator, using template literal types and recursion.
Explore how union types in TypeScript model exact application states, preventing invalid property combinations and improving safety and clarity in production-grade code.
Explore how union types represent values that can be several distinct types, and how template literal types, union of keys, and a configuration object shape runtime types.
Discover how union types distribute over operations in TypeScript, applying to template literals and property lookups, and how control flow checks narrow the resulting union into specific branches.
Merge union types in TypeScript to reduce duplication and simplify state handling, combining loading, idle, success, failed into a single comprehensive union, and introduce pending states for focused cases.
Explore how TypeScript distributes conditional types over union members, enabling recursion and string transformations like dash to space, while preserving a final union of results.
Think of every TypeScript type as a union, unifying generics and type reasoning by treating single types, unions, and the never type as sets of possible values.
Understand the never type as an empty union in TypeScript and its effect in conditional types. Compare its behavior to mapping over an empty array in JavaScript, yielding never.
Transform each union member in TypeScript with conditional types and merge the results back into a union, using an always-true constraint to force distribution and apply lowercase and uppercase.
Demonstrates how the key of operator on a union of objects returns only common keys, and shows using a distributive conditional type to obtain all keys in the union.
Explore narrowing unions in TypeScript using typeof to distinguish string, number, and boolean branches, enabling scope-specific operations like string length, numeric math, and boolean checks.
Filter union types by a type property to display only messages and alerts. Use a generic select-by-type helper that narrows the union to allowed values.
Master filtering and narrowing union types in TypeScript with the in keyword, illustrated by a booking response distinguishing confirmation from error cases.
Learn to use TypeScript's extract and exclude utilities to filter union types, leveraging template literal patterns to keep only members that start with get.
Explore how literal unions interact with a wider number type, impact TypeScript inference and autocomplete, and restore literals by wrapping the number in parentheses and intersecting with an empty object.
Learn how map types in TypeScript transform existing object types to adapt JSON API responses, converting snake_case keys to camelCase with a generic transformation function.
Map types iterate over a union, transforming each member into an object property and optionally transform its value using the key in union type syntax.
Explore how to use mapped types with the keyof operator to transform an object's properties by iterating over keys with in, producing a nullable version of the type.
Explore generic mapped types in TypeScript to derive reusable nullable or definite object types by mapping over keys, accessing value types, and using exclude to remove undefined.
Refine object keys using map types and union types to expose only public settings from server config, with omit, pick, and exclude helpers.
Learn to transform arrays and tuples with map types by wrapping each element in a value object, and extract keys from key-based tuples using conditional types and infer.
Define optional properties in TypeScript using map types and the question mark, demonstrated on product, arrays, and tuples, then convert to required with a dash-question-mark and Partial and Required.
Remap keys in a TypeScript object by turning values into functions and prefixing keys with get in camel case, using template literals and the as keyword for shaping.
Master The Complete Type System of TypeScript!
The approach of this course sets it apart from other courses. Here, the focus is exclusively on TypeScript, without wasting time on configuring trivial projects. Instead, you'll dive straight into pure TypeScript knowledge.
Rather than enduring lengthy lectures, you'll encounter real-world code challenges accompanied by concise explanations. Armed with these insights and your existing skills, you'll tackle the challenges at your own pace.
The exercises and lessons are carefully designed to reinforce key TypeScript concepts across various contexts, enabling you to understand when, where, and how to apply them effectively in your own projects.
True TypeScript experts possess a deep understanding of the language, which makes it feel straightforward and predictable rather than mysterious. The TypeScript Bible course aims to foster this level of comprehension.
Upon completing the course, you'll achieve mastery, reducing your apprehension when facing complex TypeScript errors, boosting your confidence in typing dynamic signatures, and streamlining your coding process.
By enrolling in this course:
You'll enhance your abilities as a contributor and reviewer.
You'll be the one to remove obstacles and increase productivity for others.
You'll truly grasp the inner workings of TypeScript.
This course isn't just a compilation of TypeScript tricks. Instead, it's focused on helping you develop a strong understanding of the language's fundamentals. I believe that building a solid mental model of these basics is more empowering because it equips you to tackle a wider range of problems, even those we haven't explicitly covered.
While knowing a few tricks can be helpful, true mastery comes from understanding the underlying building blocks of the language and how they interact. This deeper understanding enables you to solve real-world problems with confidence and creativity.
The initial sections of the course are designed to lay a solid foundation for you. These sections will guide you through the essential concepts and principles you'll need to grasp before delving into the more advanced and complex topics covered later in the course.
Content Description By Sections:
Sections 1,2,3:
Every programming language involves transforming data, and TypeScript is no different. However, what sets TypeScript apart is that types themselves serve as our data. In this course, we'll write programs that manipulate types as input and output other types.
To truly master TypeScript, you'll need a solid understanding of its various data types and structures. In the initial three sections, we'll delve into these concepts, exploring how they relate to the familiar concepts we use at the value level while also highlighting their unique characteristics.
Section 4:
After exploring the various types available to us in the first three sections, it's time to put our knowledge into practice by implementing our first TypeScript algorithms! This is where we transition from theory to practical application, diving into writing actual code using the language of types.
Section 5:
Next, we're going to delve into loops and recursive types. In this section, we'll harness recursion to iterate over tuple types. If recursive algorithms are new to you, the code I'll be demonstrating might seem unfamiliar at first. However, stay patient and keep in mind that we're not just mastering a new programming language, but a functional one at that! Understanding these concepts takes time, and being open to a bit of discomfort is crucial for advancing your skills.
Section 6:
Following that, we'll explore Template Literal Types, an exceptional feature exclusive to TypeScript's type system.
Section 7:
Next up, we'll delve into union types. Union types are remarkable as they allow us to accurately model the finite set of possible states our applications can be in. Without them, our types would be so imprecise that they would hardly be of any value.
Section 8:
In this section, we'll explore loops with mapped types. Here, we'll discover how to transform and filter object types using Mapped Types. We'll combine them with other features of the type system, such as Template Literal Types and Conditional Types, to construct functions with incredibly intelligent type inference.
Sections 9+ (Extra Material):
And finally, you'll find dozens of additional sections filled with even more TypeScript challenges and material to further hone your skills.
When you’ve completed the all the exercises, you’ll reach a point of mastery where you will find yourself as the typescript go-to expert in your team.
Review the course material titles to decide if it aligns with your expectations.
This course is ideal for TypeScript developers seeking to elevate their skills from intermediate to advanced levels. If this resonates with you, then this course is your next step toward mastery!