Table of Contents
Course OverviewMike provides an overview of the topics that will be covered in the course. Topics such as declaration merging, extreme types, nullish values, ES modules, generics, conditional types, mapped types, and variance over type params are mentioned.
IdentifiersMike explains how TypeScript allows for the creation of different importable and exportable things across module boundaries. The concept of namespaces and how multiple things can be stacked on top of each other in an identifier is also discussed in this segment.
ClassesMike demonstrates that classes in TypeScript are both types and values, and shows how the class declaration merges with the static field "createBanana" to create a namespace-like structure. The difference between TypeScript's read-only attributes and the Object.freeze() method is also discussed in this segment.
Top & Bottom Types
Top TypesMike discusses extreme types in TypeScript, specifically the top and bottom types. The top type, "any", can accept any value and is often used when TypeScript cannot infer a more specific type. The top type, "unknown", requires type narrowing before it can be used.
Practical Uses of Top TypesMike demonstrates how top types can be used to handle errors by using the `unknown` type in catch blocks to prevent assuming the type of the error. Using top types when receiving API responses from APIs that may change or when passing values through code that doesn't need to know about them.
object & Empty ObjectsMike discusses the object type which represents all possible values except for primitives, and it can accept functions as well. Various examples and use cases of the object type and how it can be used to remove nullability from a type by intersecting it with the empty object type are also covered in this lesson.
Bottom TypesMike discusses bottom types, which do not accept any value and represent an impossibility. An example with an unreachable error class to handle cases where unexpected values are encountered at runtime is also demonstrated in this segment.
Unit TypesMike explains that unit types are types that can only have one value, such as null and undefined. Suggestions to avoid creating variables of type void and that literal types can also be used to create unit types are also covered in this segment.
null & Non-null AssertionMike discusses the difference between null and undefined and introduces several TypeScript features and operators that can be used to handle nullish values, such as the non-null assertion operator. Examples and the potential use cases and limitations of these operators are also covered in this segment.
Definite Assignment AssertionMike discusses the definite assignment operator and explains how to use the exclamation mark (!) to assert that a variable will be assigned a value before it is used. A question about using the declare keyword instead of the exclamation mark is also covered in this segment.
Optional Chaining & Nullish CoalescingMike explains the concept of optional chaining and demonstrates how to access nested properties using optional chaining. The concept of nullish coalescing and how it can be used to set default values for variables is also discussed in this segment.
Modules & CJS Interop
ES Module Imports & ExportsMike dives into ES module imports and exports, exploring examples of named imports and exports, emphasizing the benefits of organizing code into multiple files. The example covers named imports involving consuming named exports, as well as consuming default imports.
CommonJS InteropMike explains the differences between CommonJS modules and ECMAScript modules and demonstrates how to import and export modules using both styles. Potential issues and limitations of using CommonJS modules and some alternative solutions are also discussed in this segment.
Native ES ModulesMike discusses that TypeScript supports native ES modules and introduces the different file extensions that can be used for ES modules and CommonJS modules. How to specify the module type in the package.json file and how to import a CommonJS module in TypeScript is also demonstrated in this segment.
Importing Non-TypeScript FilesMike discusses how to import non-TypeScript files, such as images or JSON, in TypeScript when using a bundler like Webpack or Parcel. How to create a global declaration file to resolve import errors for non-TypeScript files and examples of importing image files and URL modules are also covered in this segment.
Generics Scopes and Constraints
Generic ConstraintsMike reviews a TypeScript Fundamentals exercise that involved converting an array of objects to a dictionary representation and demonstrates how to implement this conversion without using generics. The use of type parameter constraints to regain flexibility while still maintaining a minimum requirement on the type parameter is also discussed in this segment.
satisfiesMike demonstrates how to use "satisfies" to retain the most specific type while still satisfying a given interface. The use of the "extends" keyword in TypeScript and how it is used to specify subtyping relationships between types is also discussed in this segment.
Scopes and TypeParamsMike discusses scopes and type parameters and explains how type parameters work similarly to variables in terms of scoping, using examples of functions and tuples. Best practices for using type parameters, emphasizing the importance of specifying constraints in the simplest way possible to maximize the flow of type information, are also discussed in this segment.
Conditional & Mapped Types
Ternary Operators & Expressing ConditionsMike introduces conditional types as a way to express type information similar to a ternary operator. How to define a conditional type that evaluates to different types based on a condition, and examples of using conditional types with literal types and union types are also covered in this segment.
Utility TypesMike introduces the concept of utility types including the "extract" and "exclude" utility types. The "extract" utility type allows you to obtain a subpart of a type that matches another type, while the "exclude" utility type allows you to obtain a subpart of a type that does not match another type.
Inference with Conditional TypesMike explains how to use the "infer" keyword to extract a specific type from a larger type within a condition. A demonstration of how to use inference to extract the type of the first argument of a function is provided in this segment.
infer ConstraintsMike discusses the TypeScript 5 feature of applying constraints to inferred type parameters and provides examples of using the "infer" keyword to extract specific types from tuples. How to express conditions and constraints on inferred type parameters, questions about rest arguments, and the use of underscores as placeholders are also covered in this segment.
Utility Types Using inferMike continues the exploration of utility types and specifically discusses the "Parameters" utility type. The "Parameters" utility type extracts the types of the arguments of a function and returns them as a tuple. Other utility types such as ReturnType, InstanceType, ThisParameterType, and OmitThisParameter are also discussed.
Record & PickMike explains that mapped types are similar to array.map for types, where you can iterate over the names of fields in one type and produce another type that is transformed in some way. How to create a mapped type called "record" that specifies a set of keys for a type and the built-in type "pick", which allows you to generate a new object type by specifying the names of some fields on a value type is also covered in this segment.
Mapping Modifiers & Template Literal TypesMike introduces mapping modifiers like `Partial`, `Required`, and `Readonly` which can be used to modify the properties of an object type. The use of template literal types to create new types by combining string literals and union types and examples of how to use mapping modifiers are also demonstrated in this segment.
Filtering PropertiesMike discusses the concept of filtering properties and demonstrates two different approaches: one where the keys are filtered first and then mapped, and another where the keys are iterated over and filtered using a conditional type. The advantages of filtering the keys first and a syntax for filtering keys using a filtering expression before the right square bracket and casting are also discussed in this segment.
Variance Over Type Params
Type Registry ExerciseMike revisits an exercise from TypeScript Fundamentals. The exercise involves building a data layer that allows fetching records based on their name and ID. The concept of a data type registry and how to use a mapped type to make the fetch record function return a promise that resolves to the correct record type are also discussed.
Variance over type ParamsMike discusses variance over type parameters using an example of a snack factory. They explain the concepts of covariance and contravariance and how they relate to subtyping relationships between different types. The instructor also demonstrates how to use the "out" and "in" keywords in TypeScript to describe covariance and contravariance respectively.
Invariance & BivarianceMike merges the Producer and Packager interfaces together to demonstrate invariance, neither covariance nor contravariance. An example of a model displaying bivariance, where function types are interchangeable in both directions. The benefits of using variance hints in type checking and how it can improve performance in large projects are also discussed in this segment.
Wrapping UpMike discusses the different courses that students can take after completing Intermediate TypeScript V2. They highlight the content and benefits of each course, and encourages students to continue their TypeScript learning journey to enhance their skills and take their code basis to the next level.