Table of Contents
IntroductionMike North provides an overview of what will be covered in the course and explains the importance of types in TypeScript and how it helps catch errors at compile time. The structure of the course and the topics that will be covered, including variables, types, generics, and more, are also discussed in this segment.
Workshop SetupMike demonstrates setting up the development environment by installing Volta, cloning the repo, and running Yarn to install the necessary dependencies. Additionally, the value of TypeScript in fullstack development and how it helps maintain type consistency between the backend and frontend is also discussed in this segment.
Variables and Values
Compiling TypeScript with TSCMike explains how the TypeScript CLI works and demonstrates it by using a Hello World TypeScript program. How the TypeScript compiler can target different language levels and generate different module formats is also discussed. Finally, the purpose of declaration files and how they allow developers to benefit from type information when using TypeScript is covered in this segment.
Variable Declarations & InferenceMike discusses the use of variables and their types. The difference between `let` and `const` declarations, literal types, type annotations, the concept of sets, and how types represent sets of allowed values are covered. This segment concludes with an example of an implicit `any` type and how to use type annotations to provide explicit types.
Any & Type CastingMike discusses typecasting in TypeScript and explains how to cast values to different types using techniques such as assigning a value to a different type, using the "as" keyword, or casting to the "any" type. TypeScript will object to casting incompatible types and suggest using the "any" type as an intermediate step when necessary.
Functions & Return TypesMike explains how to add types to a TypeScript file and demonstrates adding type annotations to a function that takes two arguments and returns a number. The benefits of using TypeScript, such as catching type errors and improving code reliability, and the use of ESLint with TypeScript are also discussed in this segment.
Objects, Arrays and Tuples
Index SignaturesMike discusses index signatures, introducing a use case where an object contains different phone numbers, including predefined and custom ones. How to define and use index signatures and conventions for accessing known properties and index fields are also covered in this segment.
Array Types, Tuples & readonlyMike discusses how TypeScript infers the type of array elements and how to define and use tuples. Using the `readonly` keyword to create immutable tuples and a discussion regarding the trade-offs of using tuples are also covered in this segment.
Structural vs Nominal TypingMike explains how type checking occurs when assigning values to variables, passing arguments to functions, and returning values from functions. Concepts such as type equivalence, static vs dynamic types, strong vs weak types, and nominal vs structural type systems are also demonstrated in this segment.
Union and Intersection Types
Conceptualizing Union & Intersection TypesMike explains how union types represent the "or" condition for types, allowing values from multiple sets, and how intersection types represent the "and" condition, requiring values to meet multiple constraints. Examples and visualizations to help students understand these concepts and build a mental model of types as sets of allowed values are provided in this segment.
Union TypesMike discusses the concept of literal types and how to create sets of specific values using union types. Questions about expressing sets without enumerating values and the use of expressions in type definitions are also covered in this segment.
Union Type Control FlowMike discusses how union types are commonly used in programs to represent different possibilities based on control flow. The concept of discriminated unions, where a literal type is used as a discriminator to determine the type of the larger value is also introduced in this segment.
Intersection TypesMike discusses intersection types and how they are different from union types. Intersection types are very picky in terms of what values they accept, but they can be used in various contexts where the behavior of both types is required.
Interfaces and Type Aliases
Type AliasMike explains the concept of interfaces and type aliases in TypeScript. How type aliases can be used to give names to types and simplify complex type definitions, how type aliases can be used in place of literal types, and how they can be extended using intersection types are also demonstrated in this segment.
Interface extends & implementsMike discusses how interfaces can be used to give a type a name and how they can be used for inheritance. The extends and implements keywords, as well as the differences between interfaces and type aliases are also covered in this segment.
Open InterfacesMike discusses re-declaring and combining interfaces, allowing for the augmentation of existing types, and the limitations of type aliases in this context. Questions from the audience regarding the implementation of interfaces and the impact of modifying interfaces on other files are also covered in this segment.
Recursive TypesMike explains the concept of recursive types using an example of nested numbers in an array. Defining a recursive type using type aliases in TypeScript and how it allows for infinitely nested arrays of numbers is also demonstrated in this segment.
JSON Type ExerciseMike provides an exercise where the goal is to define a type that accepts any valid JSON value. The solution, explaining the different types and their relationships and demonstrating how to pass all the test cases is also provided.
Type Queries, Callables & Constructables
Type QueriesMike discusses the different kinds of type queries, including key of, type of, and indexed access types. Examples and explanations of each type query and demonstrations of how they can be used to extract types from values and objects are also provided in this segment.
Type Registry PatternMike introduces the concept of the type registry pattern and explains how to use module declarations and open interfaces to create a central interface that represents a registry for different types of records. A demonstration of how this pattern can be used to easily add new types of records and achieve type checking in a web application's data layer is also covered in this segment.
CallablesMike discusses creating callable types, explains how to define a function type using an interface or a type alias, and how to specify the parameters and return type of the function. The instructor also discusses the difference between interfaces and type aliases, and when to use each one.
void TypeMike explains how "void" is used to indicate that a function does not have a return value or that the return value should be ignored. The difference between "void" and "undefined" and examples to illustrate the usefulness of "void" in certain scenarios are also covered in this segment.
Constructables & Function OverloadsMike discusses constructables and explains how to create a construct signature by adding the "new" keyword in front of a call signature. The concept of function overloads and a demonstration of how they can be used to handle different types of event handlers in a centralized event listener is also covered in this segment.
this TypesMike discusses how "this" refers to the context in which a function is called, such as the DOM element that fired an event. Explicitly providing a specific "this" type to a function using the bind method, and how to invoke the function with the correct "this" context is also covered in this segment.
Explicit Function Return TypesMike discusses best practices for functions in TypeScript. Without an explicit return type, errors may pop up in unexpected places, making it difficult to track down and fix the issue. The value of explicit return types, even if it may require extra typing is also discussed in this segment.
Classes & Type Guards
Access ModifiersMike demonstrates how to use access modifier keywords like private and protected in TypeScript to control the visibility and accessibility of class properties and methods. The difference between private and protected, and how to define private and protected fields and methods in a class are also covered in this segment.
Param Properties & OverridesMike explains that param properties allow for the creation of class fields and constructor parameters with the same names, reducing the noise in class definitions. The use of the "override" keyword in TypeScript to indicate that a method in a subclass is intended to override a method in the base class, helping with refactoring and catching misspellings, is also discussed.
Type GuardsMike discusses type guards, which are code snippets that allow the type system to make inferences about the type of a value at runtime. Examples of built-in type guards such as `instanceof`, `typeof`, and truthy-falsey checks, as well as how to define user-defined type guards are also covered in this segment.
When to Use GenericsMike introduces generics that allow for parameterizing types and creating more reusable types and provides an example of creating a dictionary from an array of objects. Solving this problem using generics, and how to define a type parameter and use it to create a more flexible and type-safe solution are also covered in this segment.
Generics Best PracticesMike gives advice on best practices for using type parameters in TypeScript functions. An example of a function with two generic types and a demonstration of how inference works for both type parameters are also provided this segment.
Dictionary ExerciseMike provides a challenge for students to write functions that mimic the behavior of map, filter, and reduce functions but for dictionaries instead of lists. Sample data and an interface for a dictionary are provided, and the goal is to write these functions so that they pass a test suite.