Skip to content 19. Avoid Cluttering Your Code with Inferable Types
- Avoid writing type annotations when TypeScript can infer the same type.
- Ideally your code has type annotations in function/method signatures but not on local variables in their bodies.
- Consider using explicit annotations for object literals and function return types even when they can be inferred. This will help prevent implementation errors from surfacing in user code.
20. Use Different Variables for Different Types
- While a variable’s value can change, its type generally does not.
- To avoid confusion, both for human readers and for the type checker, avoid reusing variables for differently typed values.
21. Understand Type Widening
- Understand how TypeScript infers a type from a constant by widening it.
- Familiarize yourself with the ways you can affect this behavior: const, type annotations, context, and as const
22. Understand Type Narrowing
- Understand how TypeScript narrows types based on conditionals and other types of control flow.
- Use tagged/discriminated unions and user-defined type guards to help the process of narrowing
23. Create Objects All at Once
- Prefer to build objects all at once rather than piecemeal. Use object spread
({...a, ...b})
to add properties in a type-safe way.
- Know how to conditionally add properties to an object.
24. Be Consistent in Your Use of Aliases
- Aliasing can prevent TypeScript from narrowing types. If you create an alias for a variable, use it consistently.
- Use destructuring syntax to encourage consistent naming.
- Be aware of how function calls can invalidate type refinements on properties. Trust refinements on local variables more than on properties.
25. Use async Functions Instead of Callbacks for Asynchronous Code
- Prefer Promises to callbacks for better composability and type flow.
- Prefer async and await to raw Promises when possible. They produce more concise, straightforward code and eliminate whole classes of errors.
- If a function returns a Promise, declare it async
26. Understand How Context Is Used in Type Inference
- Be aware of how context is used in type inference.
- If factoring out a variable introduces a type error, consider adding a type declaration.
- If the variable is truly a constant, use a const assertion (as const). But be aware that this may result in errors surfacing at use, rather than definition.
27. Use Functional Constructs and Libraries to Help Types Flow
- Use built-in functional constructs and those in utility libraries like Lodash instead of hand-rolled constructs to improve type flow, increase legibility, and reduce the need for explicit type annotations.