Table of Contents
In an Effective-style book, the title of each item is a specific piece of advice. This means that the Table of Contents forms a summary of all the advice in the book. If any item piques your curiosity and you want to learn more, order a copy.
Chapter 1: Getting to Know TypeScript
Before we dive into the details, this chapter helps you understand the big picture of TypeScript. What is it and how should you think about it? How does it relate to JavaScript? Are its types nullable or are they not? What's this about any
? And ducks?
- Understand the Relationship Between TypeScript and JavaScript
- Know Which TypeScript Options You’re Using
- Understand That Code Generation Is Independent of Types
- Get Comfortable with Structural Typing
- Limit Use of the
any
Type
Chapter 2: TypeScript’s Type System
This chapter walks you through the nuts and bolts of TypeScript's type system: how to think about it, how to use it, choices you'll need to make, and features you should avoid. TypeScript's type system is surprisingly powerful and able to express things you might not expect a type system to be able to. The items in this chapter will give you a solid foundation to build upon as you write TypeScript and read the rest of this book.
- Use Your Editor to Interrogate and Explore the Type System
- Think of Types as Sets of Values
- Know How to Tell Whether a Symbol Is in the Type Space or Value Space
- Prefer Type Declarations to Type Assertions
- Avoid Object Wrapper Types (String, Number, Boolean, Symbol, BigInt)
- Recognize the Limits of Excess Property Checking
- Apply Types to Entire Function Expressions When Possible
- Know the Differences Between
type
and interface
- Use Type Operations and Generics to Avoid Repeating Yourself
- Use Index Signatures for Dynamic Data
- Prefer Arrays, Tuples, and ArrayLike to number Index Signatures
- Use readonly to Avoid Errors Associated with Mutation
- Use Mapped Types to Keep Values in Sync
Chapter 3: Type Inference
This chapter shows you some of the problems that can arise with type inference and how to fix them. After reading it, you should have a good understanding of how TypeScript infers types, when you still need to write type declarations, and when it's a good idea to write type declarations even when a type can be inferred.
- Avoid Cluttering Your Code with Inferable Types
- Use Different Variables for Different Types
- Understand Type Widening
- Understand Type Narrowing
- Create Objects All at Once
- Be Consistent in Your Use of Aliases
- Use
async
Functions Instead of Callbacks for Asynchronous Code
- Understand How Context Is Used in Type Inference
- Use Functional Constructs and Libraries to Help Types Flow
Chapter 4: Type Design
Code is difficult to understand if you can't see the data or data types on which it operates. This is one of the great advantages of a type system: by writing out types, you make them visible to readers of your code. And this makes your code understandable. Other chapters cover the nuts and bolts of TypeScript types: using them, inferring them, and writing declarations with them. This chapter discusses the design of the types themselves. The examples in this chapter are all written with TypeScript in mind, but most of the ideas are more broadly applicable.
- Prefer Types That Always Represent Valid States
- Be Liberal in What You Accept and Strict in What You Produce
- Don’t Repeat Type Information in Documentation
- Push Null Values to the Perimeter of Your Types
- Prefer Unions of Interfaces to Interfaces of Unions
- Prefer More Precise Alternatives to String Types
- Prefer Incomplete Types to Inaccurate Types
- Generate Types from APIs and Specs, Not Data
- Name Types Using the Language of Your Problem Domain
- Consider “Brands” for Nominal Typing
Chapter 5: Working with any
Type systems were traditionally binary affairs: either a language had a fully static type system or a fully dynamic one. TypeScript blurs the line, because its type system is optional and gradual. You can add types to parts of your program but not others. This is essential for migrating existing JavaScript codebases to TypeScript bit by bit. Key to this is the any
type, which effectively disables type checking for parts of your code. It is both powerful and prone to abuse. Learning to use any
wisely is essential for writing effective TypeScript. This chapter walks you through how to limit the downsides of any
while still retaining its benefits.
- Use the Narrowest Possible Scope for
any
Types
- Prefer More Precise Variants of
any
to Plain any
- Hide Unsafe Type Assertions in Well-Typed Functions
- Understand Evolving
any
- Use
unknown
Instead of any
for Values with an Unknown Type
- Prefer Type-Safe Approaches to Monkey Patching
- Track Your Type Coverage to Prevent Regressions in Type Safety
Chapter 6: Types Declarations and @types
Dependency management can be confusing in any language, and TypeScript is no exception. This chapter will help you build a mental model for how dependencies work in TypeScript and show you how to work through some of the issues that can come up with them. It will also help you craft your own type declaration files to publish and share with others. By writing great type declarations, you can help not just your own project but the entire TypeScript community.
- Put TypeScript and
@types
in devDependencies
- Understand the Three Versions Involved in Type Declarations
- Export All Types That Appear in Public APIs
- Use TSDoc for API Comments
- Provide a Type for
this
in Callbacks
- Prefer Conditional Types to Overloaded Declarations
- Mirror Types to Sever Dependencies
- Be Aware of the Pitfalls of Testing Types
Chapter 7: Writing and Running Your Code
This chapter is a bit of a grab bag: it covers some issues that come up in writing code (not types) as well as issues you may run into when you run your code.
- Prefer ECMAScript Features to TypeScript Features
- Know How to Iterate Over Objects
- Understand the DOM hierarchy
- Don’t Rely on Private to Hide Information
- Use Source Maps to Debug TypeScript
Chapter 8. Migrating to TypeScript
You've heard that TypeScript is great. You also know from painful experience that maintaining your 15-year-old, 100,000-line JavaScript library isn't. If only it could become a TypeScript library! This chapter offers some advice about migrating your JavaScript project to TypeScript without losing your sanity and abandoning the effort.
- Write Modern JavaScript
- Use
@ts-check
and JSDoc to Experiment with TypeScript
- Use
allowJs
to Mix TypeScript and JavaScript
- Convert Module by Module Up Your Dependency Graph
- Don’t Consider Migration Complete Until You Enable
noImplicitAny