TypeScript Glossary
Key terms from the TypeScript course, linked to the lesson that introduces each one.
2,001 terms.
#
- `.d.ts` files
- alongside your compiled JavaScript.
- Lesson 82 — The --declaration Flag: Generating .d.ts FilesLesson 1178 — Global Augmentation in .d.ts Files
- `[K in keyof T]`
- This is the "mapping" part.
- Lesson 718 — The Basic Mapped Type SyntaxLesson 721 — Your First Mapped Type: StringifyLesson 845 — Event Handler Type Generation
- `alwaysStrict`
- Emits `"use strict"` in JavaScript output and parses files in strict mode
- Lesson 1180 — What strict Mode DoesLesson 1189 — Enabling strict Incrementally
- `any`
- is the escape hatch — it accepts anything *and* can be assigned to anything.
- Lesson 139 — Comparing any, unknown, and neverLesson 886 — unknown vs any: The Key Safety DifferenceLesson 906 — Type Safety Trade-offsLesson 1271 — The Problem with Untyped fetch
- `as const`
- is a **type assertion** you apply to values.
- Lesson 473 — as const vs readonly ModifiersLesson 482 — Extracting Union Members as Values
- `E`
- Stands for "Element", common in collection types
- Lesson 528 — Type Parameter Naming ConventionsLesson 613 — Result/Either Type for Error Handling
- `K`
- Stands for "Key", typically used for object keys
- Lesson 528 — Type Parameter Naming ConventionsLesson 548 — Type Parameter Naming ConventionsLesson 718 — The Basic Mapped Type Syntax
- `never`
- is the impossibility marker — *nothing* can be assigned to it (except `never` itself), and it can be assigned to anything.
- Lesson 139 — Comparing any, unknown, and neverLesson 944 — The Bottom Type ConceptLesson 946 — never vs void DistinctionLesson 977 — never vs undefined in ConditionalsLesson 1466 — Base Cases and Termination Conditions
- `noImplicitAny`
- Prevents variables from implicitly having the `any` type
- Lesson 1180 — What strict Mode DoesLesson 1189 — Enabling strict Incrementally
- `noImplicitThis`
- Flags errors when `this` has an implicit `any` type
- Lesson 1180 — What strict Mode DoesLesson 1189 — Enabling strict Incrementally
- `Path`
- The literal route pattern string (e.
- Lesson 1533 — Hono's Type-Safe Request ContextLesson 1583 — Defining zodios API Contracts
- `strictBindCallApply`
- Type-checks `.
- Lesson 1180 — What strict Mode DoesLesson 1189 — Enabling strict Incrementally
- `strictFunctionTypes`
- Ensures function parameter types are checked correctly (contravariance)
- Lesson 1180 — What strict Mode DoesLesson 1189 — Enabling strict Incrementally
- `strictNullChecks`
- Makes `null` and `undefined` distinct types that must be explicitly handled
- Lesson 1180 — What strict Mode DoesLesson 1189 — Enabling strict Incrementally
- `strictPropertyInitialization`
- Requires class properties to be initialized in the constructor
- Lesson 1180 — What strict Mode DoesLesson 1189 — Enabling strict Incrementally
- `T`
- The default "Type" parameter, used for any generic type
- Lesson 528 — Type Parameter Naming ConventionsLesson 548 — Type Parameter Naming ConventionsLesson 613 — Result/Either Type for Error Handling
- `undefined`
- → Becomes the literal string `"undefined"`:
- Lesson 824 — Template Literals with PrimitivesLesson 944 — The Bottom Type ConceptLesson 977 — never vs undefined in ConditionalsLesson 1205 — exactOptionalPropertyTypes: Optional vs Undefined
- `unknown`
- is the safe container — it accepts anything *but* requires you to check what's inside before using it.
- Lesson 139 — Comparing any, unknown, and neverLesson 187 — Generic Inference Falling Back to UnknownLesson 886 — unknown vs any: The Key Safety DifferenceLesson 906 — Type Safety Trade-offsLesson 937 — unknown in Generic ConstraintsLesson 1627 — JSON and Dynamic Data Structures
- `V`
- Stands for "Value", often paired with `K` in key-value scenarios
- Lesson 528 — Type Parameter Naming ConventionsLesson 548 — Type Parameter Naming Conventions
- `void`
- means "no useful return value" — the function completes, just with nothing meaningful
- Lesson 944 — The Bottom Type ConceptLesson 946 — never vs void Distinction
A
- Abstract classes
- can provide both contracts (abstract methods) *and* shared implementation (concrete methods).
- Lesson 1052 — Abstract Classes vs Interfaces
- Abstract members
- are contracts — methods and properties marked with the `abstract` keyword that your subclass *must* implement.
- Lesson 1053 — Extending Abstract Classes
- Acceptable scenarios
- Lesson 1609 — Suppressing Errors with @ts-ignore and @ts-expect-error
- Accuracy
- Generated types perfectly match the specification.
- Lesson 1514 — Use Code Generation for Complex Patterns
- Accurate return types
- (notice how the return type `T[K]` reflects the actual property type)
- Lesson 634 — Using keyof in Generic Constraints
- Acknowledge the limitation
- (recursive depth, unknown shape)
- Lesson 1513 — Document Limitations with Comments
- Across modules without source
- Lesson 513 — The const Enum Escape Hatch Trade-offs
- add
- the readonly modifier and `-readonly` to **remove** it.
- Lesson 741 — Adding and Removing readonly with + and -Lesson 751 — Preserving vs Overriding: When to Use +Lesson 1163 — The declare module Syntax for AugmentationLesson 1779 — Design Goals: Stability vs Innovation
- Add `any` type annotations
- to parameters, properties, and return types that would otherwise trigger `noImplicitAny` errors
- Lesson 1645 — The @ts-ignore and any Strategy
- Add intermediate type variables
- to break down multi-step checks
- Lesson 650 — Error Messages from Failed Conditional Constraints
- Add type assertions
- where the library interfaces with your code
- Lesson 884 — any in Third-Party Libraries
- Add type guards inside
- the function body to route logic correctly
- Lesson 1409 — Implementation Signature Compatibility
- Adding Prefixes
- Lesson 754 — Basic Key Transformation Patterns
- Adding Suffixes
- Lesson 754 — Basic Key Transformation Patterns
- Advanced generic constraints
- with multiple interdependent type parameters often fail or require workarounds.
- Lesson 1640 — JSDoc Limitations vs Native TypeScript
- Advantages
- You get real types instead of suppression comments, and your code becomes genuinely type-safe rather than just compile-safe.
- Lesson 1647 — Alternative Tools: TypeStat
- After (efficient)
- Lesson 1098 — Mixing type and value imports efficiently
- After adding guards (fixed)
- Lesson 892 — Migrating from any to unknown
- After exhaustive runtime validation
- , type assertions become a legitimate tool to inform the compiler about what your runtime logic has already proven.
- Lesson 1006 — After Exhaustive Runtime ValidationLesson 1015 — When Assertions Are Actually Acceptable
- After manual checks
- You've validated a value exists, but TypeScript's control flow analysis didn't catch it
- Lesson 985 — Non-Null Assertions with !
- After refactoring to unknown
- Lesson 907 — Refactoring any to unknown
- After replacing (breaks)
- Lesson 892 — Migrating from any to unknown
- After strictNullChecks
- `null` and `undefined` become their own separate types.
- Lesson 1182 — strictNullChecks Fundamentals
- After Validation
- Lesson 989 — When Assertions Are Legitimate
- Algorithmic improvements
- to type inference and constraint solving
- Lesson 1790 — Performance and Scalability Focus
- all
- on at once.
- Lesson 57 — strict: The Master Safety FlagLesson 200 — Falsy Value TypesLesson 269 — Overload Syntax: Signatures vs ImplementationLesson 354 — Aliasing Intersection TypesLesson 358 — Extending Interfaces with extendsLesson 429 — What is an Intersection Type?Lesson 433 — Multiple Type IntersectionsLesson 438 — Reading Intersection Error Messages (+11 more)
- All public API types
- interfaces, type aliases, classes you intend users to import
- Lesson 1251 — Verifying Library Type Exports
- all type checking
- for that value.
- Lesson 902 — The Problem with any: Type Safety LostLesson 908 — Function Parameters: unknown vs any
- Already-validated data
- Lesson 942 — When NOT to Use unknown
- Alternative
- Use string literal unions or plain objects with `as const`, which are already valid JavaScript patterns.
- Lesson 1772 — Features Explicitly Out of Scope
- Alternatives considered
- "Tried unknown but requires too many guards for prototype"
- Lesson 875 — Documenting Known Type Gaps
- always
- ships to your users, even if they only need one enum value.
- Lesson 522 — Bundle Size and Tree-ShakingLesson 699 — ReturnType for Async FunctionsLesson 1673 — noImplicitAny as First Defense
- Always document WHY
- Lesson 1609 — Suppressing Errors with @ts-ignore and @ts-expect-error
- Ambient declarations
- Descriptions of values, functions, and classes that exist at runtime
- Lesson 1126 — Structure of a Basic Declaration FileLesson 1150 — What declare Does: Ambient DeclarationsLesson 1160 — Declaring globalThis Extensions
- Ambiguity for tools
- Build tools can't reliably determine what's safe to remove
- Lesson 1102 — Why Type-Only Imports Exist
- Ambiguous callback scenarios
- Lesson 175 — When Context Isn't Enough
- Analogy
- Using `tsc` is like translating a letter into another language, printing it, then reading it aloud.
- Lesson 66 — Running with ts-nodeLesson 165 — Inference with Third-Party LibrariesLesson 360 — Interface Extension vs Intersection TypesLesson 464 — Preventing Widening with Type AnnotationsLesson 1189 — Enabling strict IncrementallyLesson 1198 — strictBindCallApply: Type-Safe Function MethodsLesson 1267 — Caching node_modules in CILesson 1506 — Error Messages Become Unusable (+1 more)
- Ancient TypeScript project
- → You might see `classic`, but migrate away
- Lesson 1112 — The moduleResolution Compiler Option
- any
- string key, even ones you didn't intend:
- Lesson 317 — Index Signatures and Record UtilityLesson 621 — What extends Does in Generic ConstraintsLesson 622 — Constraining to Primitive TypesLesson 999 — Runtime Safety ConsiderationsLesson 1091 — Exporting inline type definitionsLesson 1609 — Suppressing Errors with @ts-ignore and @ts-expect-error
- Any import or export
- → Module mode → Scoped declarations
- Lesson 1158 — The global Scope in .d.ts Files
- anything can be thrown
- in JavaScript—not just `Error` objects.
- Lesson 1188 — useUnknownInCatchVariablesLesson 1203 — useUnknownInCatchVariables: Safer Error Handling
- API boundaries
- (highest risk): Functions returning `any` that spread through your codebase
- Lesson 1678 — Auditing Codebases for any Usage
- API consumers
- Public APIs serving JavaScript, Python, or mobile clients need REST or GraphQL with documentation.
- Lesson 1589 — When to Choose Each Approach
- API Contract → Frontend
- Your frontend components consume the exact same types through generated clients or shared type packages
- Lesson 1310 — The End-to-End Type Safety Vision
- API contracts are fixed
- When integrating with external APIs, defining types first ensures you handle all required fields
- Lesson 1326 — Type-First vs Code-First Trade-offs
- API response data
- Keys might vary based on runtime conditions
- Lesson 310 — What Index Signatures Solve
- API Responses
- Remove backend-only fields before sending data to clients:
- Lesson 678 — Omit<T, K>: Excluding PropertiesLesson 936 — unknown for External Data Entry Points
- Applications with many files
- (React, Vue, or complex Node apps) benefit from **bundlers** like Webpack, Vite, or Parcel.
- Lesson 75 — Choosing the Right Execution Method for Your Use Case
- Apply the appropriate fix
- add `type` keyword, convert enums, or restructure exports
- Lesson 1262 — Debugging Bundler Type Issues
- ArkType
- is the newest contender, focused on runtime performance:
- Lesson 1295 — Alternatives: Yup, io-ts, ArkType
- array
- for:
- Lesson 124 — Tuples vs ArraysLesson 151 — Tuple Inference vs Array InferenceLesson 1372 — Tuple Type Inference from Literals
- Array manipulation assumptions
- Lesson 1190 — The Cost of strict: False Positives
- Array methods
- must return arrays of the same element type
- Lesson 1663 — When Generics Are Better: Type Preservation Needed
- Array mutation methods
- No `push`, `pop`, `shift`, `unshift`, `splice`, etc.
- Lesson 122 — Readonly Tuples
- Array parameters
- require the caller to construct the array explicitly:
- Lesson 267 — Rest Parameters vs Array Parameters
- Arrays
- are for homogeneous collections where:
- Lesson 124 — Tuples vs ArraysLesson 151 — Tuple Inference vs Array InferenceLesson 1370 — Tuple Types vs Array Types
- Arrow functions in callbacks
- already benefit from contextual typing and inference—adding return types here often clutters the code.
- Lesson 249 — Return Type Annotations Best Practices
- As an ES6/CommonJS import
- Lesson 1133 — UMD Module Declarations
- Ask yourself
- *Can a mid-level developer on my team understand this type in under 30 seconds?
- Lesson 1690 — The Readability Trade-offLesson 1698 — Finding the Right Abstraction Level
- Assert to Record<string, unknown>
- so you can access properties
- Lesson 927 — Validating Object Shape with Type Predicates
- assertion functions
- either succeed silently or throw an error.
- Lesson 229 — Assertion Functions BasicsLesson 233 — Assertion Functions vs Type Predicates
- Assertions at Module Boundaries
- Lesson 1016 — Code Review Red Flags with Assertions
- Assertions provide zero safety
- Lesson 991 — Prefer Type Guards Over Assertions
- Assertions to Satisfy Tests
- Lesson 1016 — Code Review Red Flags with Assertions
- Assertions Without Justification Comments
- Lesson 1016 — Code Review Red Flags with Assertions
- Assignability relationships
- Whether type A is assignable to type B
- Lesson 1704 — The Type Cache and Memoization
- Asynchronous Code
- Lesson 403 — Control Flow Analysis Limitations
- at compile time
- and the assignment line never needs to run.
- Lesson 961 — Exhaustiveness Without Runtime CodeLesson 1712 — The Cost of Deep Conditional Types
- At compile-time
- as a union type for parameters or variables.
- Lesson 482 — Extracting Union Members as Values
- At declaration
- Lesson 1018 — Basic Class Property TypingLesson 1023 — Readonly PropertiesLesson 1199 — strictPropertyInitialization: Required Class Properties
- At runtime
- as values in an array for looping, validation, etc.
- Lesson 482 — Extracting Union Members as Values
- at the type level
- .
- Lesson 638 — keyof and Mapped Types TogetherLesson 831 — Uppercase<T> for Full Capitalization
- augment
- the library's interfaces directly in your own codebase using declaration merging.
- Lesson 365 — Augmenting Third-Party InterfacesLesson 372 — When Declaration Merging Is DesirableLesson 1171 — When to Augment vs Fork Types
- Augment when
- Lesson 1171 — When to Augment vs Fork Types
- Authentication state
- Include `user: User | null` to represent logged-in vs anonymous requests.
- Lesson 1545 — Context Typing for Procedures
- Auto-generated types
- from APIs with hundreds of endpoints
- Lesson 1721 — Type Checking Large Union Types
- autocomplete
- .
- Lesson 4 — Autocomplete and IntelliSense BenefitsLesson 36 — Editor Support and Language ServicesLesson 179 — Implicit any from Untyped ParametersLesson 466 — When to Use Literal TypesLesson 520 — Refactoring Safety and AutocompleteLesson 634 — Using keyof in Generic ConstraintsLesson 685 — Record vs Index SignaturesLesson 1642 — Validating JSDoc Coverage with Tooling (+1 more)
- Autocomplete matters
- Users should see exactly what's allowed
- Lesson 1662 — When Unions Are Better: Known Fixed Options
- Autocomplete stops working
- or becomes extremely slow
- Lesson 1752 — Restart Language Service When Stuck
- Autocomplete works
- Your editor suggests only valid keys
- Lesson 317 — Index Signatures and Record Utility
- Autocompletion and documentation
- Lesson 1509 — Embrace Runtime Checks Over Type Gymnastics
- Automated migration tools
- change the game for all-at-once conversions.
- Lesson 1620 — When All-at-Once Actually Works
- Automatic typing
- TypeScript infers the `input` parameter's type from the schema using `z.
- Lesson 1542 — Input Validation with Zod Schemas
- automatically narrows
- the type in that branch.
- Lesson 224 — Narrowing with Type PredicatesLesson 889 — Assertion Functions with unknown
- Automatically rebuilds
- only the affected projects when changes are detected
- Lesson 1230 — Watch Mode with Project References
- Avoid `const enum` when
- Lesson 506 — When to Use const enums
- Avoid `const enums` entirely
- in projects using Babel/esbuild
- Lesson 504 — const enums and isolatedModules
- Avoid circular type dependencies
- When two files import types from each other, TypeScript must resolve them together, which is expensive.
- Lesson 1745 — Minimize File-Level Type Dependencies
- Avoid confusion
- Prevents accidentally trying to use a type as if it were a value, especially when re-exporting from barrel files.
- Lesson 1096 — Type-only export syntax with export type
- Avoid declaration merging when
- Lesson 369 — When to Leverage Declaration Merging
- Avoid Generic Noise Words
- Lesson 1659 — Naming Conventions for Focused Types
- Avoid intersections when
- Lesson 455 — Avoiding Intersection Overuse
- Avoid perfectionism
- A "good enough" migration that ships beats a perfect one that stalls at 60%
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- Avoiding circular dependencies
- Type-only imports don't create runtime module dependencies
- Lesson 1109 — Type-Only Import Best Practices
- Avoiding name collisions
- between different parts of a large API
- Lesson 1143 — Namespaces in Declarations
B
- Babel
- , **esbuild**, and **swc** compile TypeScript files *one at a time* without seeing the whole project—they just strip types away quickly.
- Lesson 1253 — What isolatedModules DoesLesson 1258 — When to Enable isolatedModules
- Backend developers
- can implement endpoints knowing exactly what shape must be returned
- Lesson 1332 — Collaborating Through Type Definitions
- Backward compatibility matters
- Adding defaults doesn't break existing code
- Lesson 570 — When to Use Defaults vs Required Parameters
- Base behavior
- from a class hierarchy (shared implementation)
- Lesson 1055 — Combining implements and extends
- Base case
- If not an object (primitives, functions, etc.
- Lesson 812 — The DeepPartial PatternLesson 1447 — Building Awaited with inferLesson 1742 — Avoid Recursive Types Without Base Cases
- Before (verbose)
- Lesson 1098 — Mixing type and value imports efficiently
- Before strictNullChecks
- `null` and `undefined` are assignable to *every* type.
- Lesson 1182 — strictNullChecks Fundamentals
- Benefit
- Write generic, reusable functions once.
- Lesson 1502 — Libraries That Use HKT Simulation: fp-ts
- Benefits
- Lesson 1092 — Named exports vs default exports for typesLesson 1237 — Bundler Loaders: ts-loader and babel-preset-typescript
- Best Common Type
- algorithm to figure out array types and conditional expressions.
- Lesson 174 — Best Common Type in ContextLesson 1702 — Constraint Solving and Unification
- Best for
- Public APIs, library functions, data parsing, external input handling — anywhere safety matters more than convenience.
- Lesson 909 — Return Types: When Each Makes SenseLesson 1599 — The Bottom-Up vs Top-Down Decision
- Best practice
- Only use prototype manipulation when absolutely necessary (polyfills, framework requirements).
- Lesson 1629 — Prototype Manipulation and Monkey-Patching
- Beta releases
- are more stable previews, typically 2-4 weeks before a final release.
- Lesson 1780 — Features in Active DevelopmentLesson 1785 — Community Feedback and Breaking Changes
- Better
- Create focused functions with specific types, or use a generic constrained to the types you actually need.
- Lesson 1736 — Use Specific Types Instead of Unions When Possible
- Better code review
- Reviewers see type issues highlighted alongside code changes
- Lesson 1270 — Reporting Type Errors in Pull Requests
- Better for shared libraries
- If multiple parts of your codebase use common helpers, typing them creates widespread benefit
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- Better for tight loops
- If you're checking enum values thousands of times per second (like in game loops or data processing), eliminating those property lookups removes tiny but cumulative overhead.
- Lesson 502 — Performance Benefits of const enums
- Better inference
- TypeScript naturally narrows unions through your implementation
- Lesson 1408 — Union Signatures for Shared Logic
- Better interoperability
- When working with external APIs, JSON data, or JavaScript libraries, you're already dealing with plain strings.
- Lesson 515 — Community Preference for Unions
- Better library support
- More built-in methods accepting BigInts
- Lesson 1764 — Numeric Separators and BigInt Evolution
- Blazing fast startup
- Bun's transpiler is written in highly optimized code (Zig language), making it significantly faster than alternatives
- Lesson 71 — Running TypeScript in Bun
- Boilerplate explosion
- Every type constructor needs its own interface definition.
- Lesson 1489 — TypeScript's Workaround: Interface Pattern
- Boolean combinations
- that create contradictions (`isLoading: boolean` + `data: User | null` + `error: Error | null`)
- Lesson 1346 — Refactoring Toward Impossible States
- both
- modifiers on a single property.
- Lesson 305 — Combining Optional and ReadonlyLesson 363 — Merging Function Overloads in InterfacesLesson 431 — Intersecting Object TypesLesson 438 — Reading Intersection Error MessagesLesson 440 — Primitive Type IntersectionsLesson 447 — Intersection Order IndependenceLesson 452 — Combining Interface and Type AliasLesson 713 — NoInfer<T> for Disabling Inference (+3 more)
- Bottleneck hotspots
- Specific type operations causing delays
- Lesson 1730 — Using @typescript/analyze-trace CLI
- bottom type
- it represents values that *never occur*.
- Lesson 134 — Introduction to never: The Bottom TypeLesson 944 — The Bottom Type ConceptLesson 948 — Assignability Rules for never
- Bottom-up
- Start with utility files and shared modules that have few dependencies.
- Lesson 1614 — The File-by-File Incremental Strategy
- Bottom-up inference
- starts with the literal values or expressions you write and infers types moving upward through your code.
- Lesson 1700 — Type Inference Flow: Bottom-Up and Top-Down
- Bottom-up migration
- means starting with low-level utility functions and data structures that other parts of your code depend on.
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- boundary
- where untrusted data enters your system (API responses, JSON parsing, user uploads).
- Lesson 942 — When NOT to Use unknownLesson 1679 — Localized any with Strict Boundaries
- Bounded flexibility
- Only specific types allowed (union behavior)
- Lesson 1666 — Generic Constraints vs Union Bounds
- bracket notation
- with a numeric literal to index into the tuple, just like accessing array positions.
- Lesson 701 — Accessing Individual ParametersLesson 1206 — noPropertyAccessFromIndexSignature: Explicit Index Access
- brand technique
- solves this by adding a fake, unique property to each type using a **symbol** and an **intersection type**.
- Lesson 1350 — Brand Technique with IntersectionLesson 1360 — What Opaque Types Are
- branded type
- is a type that carries a compile-time "tag" or "brand" to distinguish it from other structurally identical types.
- Lesson 658 — Branded Type ConstraintsLesson 1345 — Empty Array Edge Cases
- Branded/opaque types
- cannot be properly created since they rely on unique symbols or complex intersections.
- Lesson 1640 — JSDoc Limitations vs Native TypeScript
- Branding
- solves this by tagging primitive types with unique compile-time markers.
- Lesson 1353 — Branding Primitive Types
- Breaking at usage sites
- Forces you to add type guards where the value is actually used
- Lesson 1676 — Replacing any with unknown for Safe Migration
- Breaking changes risk
- Adding HKTs would likely require fundamental changes to how generics work, potentially breaking millions of lines of existing TypeScript code.
- Lesson 1494 — The TC39 and TypeScript Roadmap on HKTs
- Browser environment (`Window`)
- Lesson 1174 — Augmenting Built-in Global Interfaces
- Browser storage
- – localStorage, sessionStorage, cookies
- Lesson 936 — unknown for External Data Entry Points
- Build mode
- (`tsc --build`): Compile multiple related projects efficiently
- Lesson 76 — Understanding Compilation Modes: Build vs Watch vs Project
- Build pipelines
- where type-checking and transpilation are separate steps
- Lesson 1245 — What emitDeclarationOnly Does
- Build scripts
- Running utility scripts that don't need full type-checking
- Lesson 67 — tsx: A Faster Alternative to ts-node
- Build speed
- – How quickly `tsc` can complete a full compilation
- Lesson 1790 — Performance and Scalability Focus
- Build time increases
- type instantiation happens repeatedly
- Lesson 1741 — Break Large Union Types into Smaller Chunks
- Build times increase noticeably
- after adding path types
- Lesson 865 — Practical Limits of Path Type Complexity
- Build tool optimization
- Tools like bundlers and compilers can safely strip these exports without worrying about side effects, potentially improving tree-shaking.
- Lesson 1096 — Type-only export syntax with export type
- builder pattern
- lets you construct complex objects step-by-step using a fluent chain of method calls.
- Lesson 596 — Generic Builder PatternLesson 1075 — Typing Methods That Return this
- Builders
- that need method chaining with type accumulation
- Lesson 1663 — When Generics Are Better: Type Preservation Needed
- building block
- of generic programming.
- Lesson 609 — The Identity Function PatternLesson 1222 — Enabling composite: true
- Building libraries
- where a faster tool (like esbuild or swc) handles the actual JavaScript compilation, but you still need TypeScript's declaration files for type safety
- Lesson 1245 — What emitDeclarationOnly Does
- Bun
- takes this further with a TypeScript runtime built in Zig.
- Lesson 1792 — Ecosystem Integration: Bundlers and Runtimes
- Bundle size optimization
- Helps bundlers tree-shake more effectively
- Lesson 1109 — Type-Only Import Best Practices
- Bundler
- Transforms code, optimizes bundles, handles imports
- Lesson 1236 — Using tsc --noEmit for Type-Checking OnlyLesson 1246 — When Libraries Need Declaration Files Only
- Bundler efficiency
- Clearly marks what's type-only, enabling better tree-shaking
- Lesson 1104 — Mixed Imports: Types and Values
- bundlers
- like Webpack, Vite, or Parcel.
- Lesson 75 — Choosing the Right Execution Method for Your Use CaseLesson 1234 — Bundlers: Webpack, Rollup, esbuild, and OthersLesson 1237 — Bundler Loaders: ts-loader and babel-preset-typescriptLesson 1248 — Bundler-First Library WorkflowsLesson 1796 — Long-Term Vision: TypeScript as a Platform
- Business logic modules
- Clear, readable functions that solve domain problems
- Lesson 1515 — Separate Business Logic from Type Acrobatics
- Business rules
- (age ranges, string formats, relational constraints)
- Lesson 1509 — Embrace Runtime Checks Over Type Gymnastics
- Business rules or constraints
- exist that types can't express
- Lesson 1684 — JSDoc Comments for Public APIs
C
- Cache fewer results
- because `any` invalidates assumptions
- Lesson 1723 — The any Pollution Performance Hit
- Cache intermediate results
- using type aliases.
- Lesson 1448 — Performance Considerations with Complex infer
- Cache results
- (which consumes memory)
- Lesson 1712 — The Cost of Deep Conditional TypesLesson 1749 — Complex Types and Autocomplete Lag
- call signature
- lets you describe this pattern in TypeScript: an object that is both callable *and* has properties.
- Lesson 241 — Call SignaturesLesson 347 — Interfaces for Function Types
- Callable on component mount
- without side effects
- Lesson 1561 — What Distinguishes Queries from Mutations
- Callback parameters
- Event handlers or middleware receive `any` arguments
- Lesson 884 — any in Third-Party Libraries
- Can engineers refactor safely
- (Do they get errors when breaking changes happen?
- Lesson 1602 — When to Stop and Ship
- Can you start small
- TypeScript lets you rename `.
- Lesson 30 — When to Choose TypeScript Over Alternatives
- cannot
- become outdated.
- Lesson 5 — Self-Documenting Code Through TypesLesson 89 — The bigint TypeLesson 493 — Computed Enum MembersLesson 622 — Constraining to Primitive TypesLesson 922 — Error Handling with unknownLesson 950 — Array and Object with neverLesson 961 — Exhaustiveness Without Runtime CodeLesson 1169 — Common Pitfalls in Module Augmentation (+5 more)
- Cap property count
- objects with 20+ properties per level kill performance
- Lesson 865 — Practical Limits of Path Type Complexity
- Capability contracts
- from interfaces (what the class can do)
- Lesson 1055 — Combining implements and extends
- capture
- the `this` value from the surrounding scope where they're *defined*.
- Lesson 285 — Arrow Functions and this CaptureLesson 1435 — Basic infer Pattern: Extracting Array Element Types
- Case Transformation
- Lesson 754 — Basic Key Transformation Patterns
- Catching errors before deployment
- Type errors become blockers that must be fixed before code reaches production.
- Lesson 1263 — Why Type-Check in CI
- Celebrate milestones
- When you hit 25%, 50%, 75% converted—acknowledge it
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- chain
- of method calls that reads smoothly, like sentences in natural language.
- Lesson 1067 — Method Chaining with thisLesson 1462 — Building Custom Extraction Utilities
- Chain multiple remapped types
- (a remapped type that consumes another remapped type)
- Lesson 764 — Performance Considerations with as
- Chain multiple variadic transformations
- (reversing a flattened concatenation of extracted tuples)
- Lesson 1395 — Performance Considerations with Complex Variadics
- Chainable methods
- (configuration, setup) return `this` to enable fluent interfaces
- Lesson 1078 — Mixing Chainable and Non-Chainable Methods
- Chained generic transformations
- (mapping over mapped types over mapped types)
- Lesson 1711 — Understanding Type Instantiation Depth
- Chains of dependent constraints
- Lesson 1722 — Generic Constraint Resolution Overhead
- Changes are caught early
- if you annotate a return type and then modify the function body, TypeScript immediately flags mismatches
- Lesson 166 — Balancing Inference and Explicitness in Teams
- Changes ripple unpredictably
- through inference chains
- Lesson 1480 — The Maintenance Burden of Clever Types
- Changes surface immediately
- if the API team modifies a type, the frontend sees compiler errors before any code runs
- Lesson 1332 — Collaborating Through Type Definitions
- Check it's an object
- (not null, not primitive)
- Lesson 927 — Validating Object Shape with Type Predicates
- Check the tooling landscape
- TypeScript has DefinitelyTyped, meaning almost every popular library has type definitions ready.
- Lesson 30 — When to Choose TypeScript Over Alternatives
- Checks for `exports` first
- if present, uses only those paths
- Lesson 1116 — The exports Field for Modern Packages
- Choose clarity
- If explaining your type takes more than a sentence, consider simplifying it.
- Lesson 1516 — Prioritize Developer Experience Over Perfect Types
- Chop
- Cut vegetables into small pieces" (method style) or "**Chopping instruction:** (how to cut vegetables)" (property style).
- Lesson 292 — Function Properties in Object Types
- Chopping instruction
- (how to cut vegetables)" (property style).
- Lesson 292 — Function Properties in Object Types
- CI runs `tsc --noEmit`
- to type-check without emitting files
- Lesson 1270 — Reporting Type Errors in Pull Requests
- CI/CD pipelines
- Your build tool (like Vite or Webpack) already handles compilation, so you just want TypeScript to validate types before deployment
- Lesson 74 — Running Type Checks Without Emitting FilesLesson 1746 — Use Incremental Compilation and Build Modes
- Circular dependency risks
- Type-level imports might create cycles that break module loading
- Lesson 1102 — Why Type-Only Imports Exist
- Circular references
- between procedures or router types can create impossible inference puzzles.
- Lesson 1580 — Type Inference Limitations and Workarounds
- Circular type references
- that create recursive inference chains
- Lesson 1717 — The Hidden Cost of Inference
- Clarity
- The `export` keyword at the start immediately signals "this type is public API.
- Lesson 1091 — Exporting inline type definitionsLesson 1096 — Type-only export syntax with export type
- Clarity matters more
- Merged interfaces scatter definition across files, making them harder to understand
- Lesson 369 — When to Leverage Declaration Merging
- Class ownership
- Static properties live on the class constructor function itself.
- Lesson 1056 — Static Properties Basics
- Cleaner semantics
- The type system understands these are abstract markers, not real properties.
- Lesson 1351 — Declaring Brand Symbols
- Clear dependency graph
- `references` explicitly document what depends on what
- Lesson 1229 — Monorepo Patterns with References
- Clearer boundaries
- Only the public API (what's exported) is visible, enforced by declarations
- Lesson 1227 — Cross-Project Imports
- Clearer project boundaries
- (enforced separation of concerns)
- Lesson 1221 — What Are Composite Projects?
- Client-side optimizations
- React Query (used by tRPC's React client) caches queries but handles mutations differently
- Lesson 1563 — tRPC mutation() Method Basics
- Client-side types
- The tRPC client automatically knows what shape of data to send, with full autocomplete.
- Lesson 1542 — Input Validation with Zod Schemas
- Code review guidelines
- specific to TypeScript (not just general review)
- Lesson 1601 — Team Coordination During Migration
- Code review quality
- Reviewers can focus on logic and architecture instead of catching type mistakes manually.
- Lesson 1263 — Why Type-Check in CI
- Code Rot Sets In
- Lesson 898 — The Danger of Suppression Comments
- Code transformation tools
- that analyze and modify TypeScript code
- Lesson 1796 — Long-Term Vision: TypeScript as a Platform
- Code-First
- You write working JavaScript-style code first, adding minimal type annotations, then refactor and strengthen types as patterns emerge.
- Lesson 1326 — Type-First vs Code-First Trade-offs
- Code-first is advantageous when
- Lesson 1326 — Type-First vs Code-First Trade-offs
- Cognitive load compounds
- What made sense in isolation becomes a maintenance burden when multiplied across a large codebase
- Lesson 1695 — Maintainability Over Time
- cognitive overhead
- slows everyone down.
- Lesson 380 — Consistency Within a Codebase Matters MostLesson 1480 — The Maintenance Burden of Clever Types
- Cognitive overload
- Developers trying to understand *what* the code does must also parse *how* the types work
- Lesson 1515 — Separate Business Logic from Type AcrobaticsLesson 1651 — The Readability Problem with Giant Union Types
- Collisions
- Your method might conflict with future standard additions
- Lesson 1629 — Prototype Manipulation and Monkey-Patching
- Comment your conditional constraints
- to explain intent
- Lesson 650 — Error Messages from Failed Conditional Constraints
- Common pattern
- Many projects create a `types/` or `typings/` folder at the root and add it to `include`:
- Lesson 1167 — Placement and Scope of Augmentation Files
- CommonJS
- (used in older Node.
- Lesson 58 — esModuleInterop: Bridging Module SystemsLesson 1121 — ESM vs CommonJS Resolution Differences
- Communicate intent clearly
- to other developers (and your future self)
- Lesson 1339 — Splitting Types by Context
- communication
- .
- Lesson 159 — Annotating for Documentation ValueLesson 1686 — Type Aliases vs Inline Types for Clarity
- Community Outreach
- Major changes are announced in blog posts, Twitter threads, and Discord discussions well before release.
- Lesson 1785 — Community Feedback and Breaking Changes
- Community Scripts
- Many teams build custom AST-based tools using the TypeScript Compiler API to handle project- specific patterns
- Lesson 1648 — Alternative Tools: dts-gen and Others
- Compatibility is non-negotiable
- TypeScript's success depends on staying aligned with JavaScript.
- Lesson 1755 — TC39 and ECMAScript: The Foundation
- Compatibility with JavaScript
- types are erased at runtime
- Lesson 1486 — Why TypeScript Lacks True HKTs
- Compilation Tests
- Lesson 1321 — Testing End-to-End Type Safety
- compile time
- instead of discovering them in production.
- Lesson 1310 — The End-to-End Type Safety VisionLesson 1564 — Type Inference Across Query Procedures
- compile-time
- tool.
- Lesson 1117 — Extension Resolution: .ts vs .jsLesson 1534 — Path Parameters and Validation in Hono
- Compile-time errors
- are like spelling and grammar mistakes you catch *before* submitting—your spell-checker flags them immediately.
- Lesson 2 — Runtime Errors vs Compile-Time ErrorsLesson 466 — When to Use Literal TypesLesson 474 — as const for Configuration ObjectsLesson 1575 — Context Type Propagation
- compile-time guarantee
- the TypeScript compiler refuses to build your code until you handle all possibilities.
- Lesson 423 — Compile-Time vs Runtime GuaranteesLesson 954 — What Is an Exhaustive Check?
- Compile-time safety
- when accessing properties
- Lesson 634 — Using keyof in Generic ConstraintsLesson 909 — Return Types: When Each Makes Sense
- Compile-time type
- `Status` for parameters and variables.
- Lesson 482 — Extracting Union Members as Values
- Compile-time types
- TypeScript checks your code before it runs
- Lesson 1298 — The Problem: Duplication Between Runtime and Type ChecksLesson 1557 — Input Validation with Zod Integration
- Compile-time values
- All enum members have constant values known at compile time
- Lesson 506 — When to Use const enums
- Compiler Speed
- The time it takes to run `tsc` from start to finish.
- Lesson 1781 — Performance and Scalability Focus
- Compiler-guided
- TypeScript errors show you exactly where assumptions were made
- Lesson 1676 — Replacing any with unknown for Safe Migration
- Complex business logic
- with nuanced type requirements will defeat automated tools.
- Lesson 1649 — When Automation Helps vs Manual Migration
- Complex Conditional Logic
- Lesson 403 — Control Flow Analysis LimitationsLesson 1509 — Embrace Runtime Checks Over Type Gymnastics
- Complex Domain Modeling
- Systems with intricate business rules (financial calculations, state machines, workflow engines) benefit immensely.
- Lesson 1333 — When Type-First Design Pays Off
- Complex functions
- benefit from annotations because they serve as documentation.
- Lesson 249 — Return Type Annotations Best Practices
- Complex inferred types
- that take seconds to display
- Lesson 1448 — Performance Considerations with Complex infer
- Complex mapped types
- where lookups compound
- Lesson 1739 — Use Type Parameters Instead of LookupsLesson 1749 — Complex Types and Autocomplete Lag
- Complex module resolution
- Searching `node_modules` hierarchies is expensive
- Lesson 1710 — Symbol Table Lookups and Resolution
- Complex object literals
- Lesson 175 — When Context Isn't Enough
- Complex parsing logic
- Template literals can't encode runtime behavior—use validators.
- Lesson 828 — Limitations of Template Literals
- Complex transformations
- using conditionals and nested mapped types
- Lesson 1738 — Cache Expensive Mapped Type Results
- Complex type tooltips
- that take seconds to display
- Lesson 839 — Performance and Complexity Considerations
- Complex union narrowing
- Large unions being filtered through many conditions
- Lesson 1709 — Control Flow Analysis Overhead
- Complexity cost
- Does it make the language harder to learn or maintain?
- Lesson 1793 — The Role of Community Feedback
- Complexity explosion
- HKTs would introduce a level of abstraction that conflicts with TypeScript's goal of being accessible.
- Lesson 1494 — The TC39 and TypeScript Roadmap on HKTs
- Composite projects
- with `composite: true` enable incremental builds and project references.
- Lesson 1250 — Combining with Composite Projects
- Concatenate
- the flattened first element with the flattened rest
- Lesson 1383 — Flattening Nested Tuples
- Concrete members
- are ready-to-use — methods and properties that already have implementations.
- Lesson 1053 — Extending Abstract Classes
- Conditional chaining
- means your methods selectively return `this` based on runtime logic, while TypeScript still tracks the type correctly.
- Lesson 1079 — Conditional Chaining with this
- Conditional check
- `T extends object` asks "Is this type an object?
- Lesson 812 — The DeepPartial PatternLesson 813 — The DeepReadonly Pattern
- Conditional constraints
- let you write `extends` clauses that check a condition and enforce different constraints based on the result.
- Lesson 646 — Conditional Constraints for Function Signatures
- conditional logic
- right in your `extends` clause using the syntax `T extends Condition ?
- Lesson 643 — Using Conditionals in extends ClausesLesson 757 — Conditional Key RemappingLesson 847 — Conditional Key Generation
- Conditional modifier application
- combines mapped types with conditional types to make dynamic decisions about whether to apply `?
- Lesson 748 — Conditional Modifier Application
- Conditional type approach
- Lesson 778 — Readability vs Power Trade-offs
- Conditional type resolutions
- The outcome of `T extends U ?
- Lesson 1704 — The Type Cache and Memoization
- conditional types
- with **extends constraints** and **keyof**, you can create a type-safe event system where the handler's parameter type automatically matches the event name.
- Lesson 651 — Real-World Pattern: Type-Safe Event HandlersLesson 848 — Nested Property Path GenerationLesson 853 — Recursive Path Types for Deep ObjectsLesson 856 — Building URL Builder FunctionsLesson 971 — Filtering Union Members with neverLesson 1429 — Conditional Method AvailabilityLesson 1503 — The Complexity Tax of HKT SimulationLesson 1640 — JSDoc Limitations vs Native TypeScript
- Configuration merging
- where defaults fill in all optional fields
- Lesson 723 — Making All Properties Required
- Configuration objects
- Some settings have defaults, so users don't need to specify everything
- Lesson 664 — The Partial<T> UtilityLesson 1414 — What const Type Parameters SolveLesson 1593 — Choosing Your First Files
- Conflicting `paths` mappings
- Lesson 1123 — Troubleshooting Common Resolution Errors
- Confusion Has Real Consequences
- Lesson 1369 — When Opaque Types Add Value
- Connect your form library
- to use both the runtime validation and compile-time types
- Lesson 1317 — Type Safety in Form Handling
- Consider lazy loading
- For admin panels or infrequent operations, load validation libraries only when needed rather than in your main bundle.
- Lesson 1297 — Performance and Bundle Size Considerations
- Consider runtime alternatives
- For very large sets, plain JavaScript might be more appropriate
- Lesson 839 — Performance and Complexity Considerations
- Consider splitting
- separate shallow path types from deep ones
- Lesson 865 — Practical Limits of Path Type Complexity
- Consistency
- Matching your team's coding style
- Lesson 244 — Explicitly Typing Callback ParametersLesson 380 — Consistency Within a Codebase Matters MostLesson 663 — What Are Utility Types?Lesson 1032 — public: The Default VisibilityLesson 1518 — Typing Component Props with Interfaces
- Const Assertions Evolution
- Lesson 19 — TypeScript 5.x: Modern Features
- const enums
- inline their values at compile time to eliminate runtime overhead.
- Lesson 513 — The const Enum Escape Hatch Trade-offsLesson 1255 — Const Enums Break Without Cross- File Context
- Const Type Parameters
- Lesson 19 — TypeScript 5.x: Modern Features
- constraint
- (only valid HTTP methods) and **precision** (the exact literal type is preserved).
- Lesson 628 — Constraints with Union TypesLesson 1423 — When Not to Use const Type Parameters
- Constraint `extends`
- "T *must* be assignable to U" — enforces a requirement
- Lesson 766 — The extends Keyword in Conditionals
- Constraint solving
- is the algorithmic process where TypeScript examines all the contexts where a type parameter appears, collects requirements (constraints), and finds a type that satisfies all of them simultaneously.
- Lesson 1702 — Constraint Solving and UnificationLesson 1707 — Contextual Typing Performance
- Constraints are visible
- an annotated variable shows what you *intended* to allow, not just what TypeScript happened to infer from the first value
- Lesson 166 — Balancing Inference and Explicitness in Teams
- Construct the current path
- using template literal types
- Lesson 852 — Constructing Path Unions from Object Keys
- Constructor signature
- What parameters the class accepts when instantiated
- Lesson 1141 — Declaring Classes
- Consumer convenience
- `useTheme()` returns `ThemeContextType`, not `ThemeContextType | undefined`
- Lesson 1526 — Typing Context Providers with createContext
- Context mutations in middleware
- where the shape changes dramatically may confuse inference.
- Lesson 1580 — Type Inference Limitations and Workarounds
- context object
- (`c`) that knows exactly what route you're on, what parameters exist, what your environment variables are, and what shape your request body has—all at compile time.
- Lesson 1533 — Hono's Type-Safe Request ContextLesson 1545 — Context Typing for Procedures
- Contextual hints
- about why a type didn't match
- Lesson 1791 — Better Error Messages and Developer Experience
- contextual typing
- the surrounding code provides type context, so you don't have to annotate everything manually.
- Lesson 167 — What Is Contextual TypingLesson 168 — Function Parameter ContextLesson 169 — Array Method CallbacksLesson 245 — Typing Anonymous FunctionsLesson 1700 — Type Inference Flow: Bottom-Up and Top-Down
- Continuous Integration (CI)
- is your automated build pipeline — the system that runs whenever code is pushed or a pull request is opened.
- Lesson 1263 — Why Type-Check in CI
- contract
- "If this function returns true, you can trust that the value is this specific type.
- Lesson 224 — Narrowing with Type PredicatesLesson 398 — Type Predicates for Custom NarrowingLesson 529 — How Type Parameters Flow Through CodeLesson 1273 — Creating Response Type InterfacesLesson 1534 — Path Parameters and Validation in HonoLesson 1585 — ts-rest Contract Structure
- Contract-First Approaches
- like JSON Schema or Protocol Buffers define types in a separate specification language, then generate TypeScript.
- Lesson 1581 — The End-to-End Type Safety Landscape
- contravariance
- for function parameters.
- Lesson 1183 — strictFunctionTypes and ContravarianceLesson 1197 — strictFunctionTypes: Contravariant Function Parameters
- Contravariant position
- Function parameters.
- Lesson 801 — Covariance and Contravariance with inferLesson 1444 — Covariance and Contravariance with infer
- Contravariant positions
- (function parameters): TypeScript creates an **intersection** of all possible matches
- Lesson 800 — Union Collapse with Multiple infer Sites
- control flow analysis
- TypeScript traces through your `if`/`else` statements to determine what's possible where.
- Lesson 102 — Type Guards for PrimitivesLesson 196 — Control Flow Analysis After typeofLesson 947 — Empty Union ResolutionLesson 1709 — Control Flow Analysis Overhead
- Control flow narrowing
- Narrowing `string | number` with `typeof` requires expansion to determine what remains.
- Lesson 1708 — Union and Intersection Expansion
- Control flow safety
- (`noFallthroughCasesInSwitch`, `noImplicitReturns`) catches logic errors but doesn't enforce property initialization.
- Lesson 1220 — Combining Safety Flags for Maximum Protection
- Convention
- It's the most common pattern in TypeScript codebases—most libraries export types this way.
- Lesson 1091 — Exporting inline type definitions
- Convert everything when
- Lesson 1602 — When to Stop and Ship
- Converting to event names
- Lesson 840 — Mapping Keys to Template Literal Types
- Correct export statements
- types appear with proper `export` keywords
- Lesson 1251 — Verifying Library Type Exports
- Correctness Fixes
- When a type-checking bug allows unsafe code, fixing it breaks programs that relied on the bug.
- Lesson 1785 — Community Feedback and Breaking Changes
- Cost
- Steep learning curve, verbose type annotations, and complex error messages.
- Lesson 1502 — Libraries That Use HKT Simulation: fp-ts
- Covariant position
- Return types and properties you *read from*.
- Lesson 801 — Covariance and Contravariance with inferLesson 1444 — Covariance and Contravariance with infer
- Covariant positions
- (return types, promise contents): TypeScript creates a **union** of all possible matches
- Lesson 800 — Union Collapse with Multiple infer Sites
- create
- them in practice.
- Lesson 383 — Creating Simple Union TypesLesson 1772 — Features Explicitly Out of Scope
- Create custom type declarations
- that override or augment the library
- Lesson 884 — any in Third-Party Libraries
- Creates large intermediate types
- (massive unions, distributed conditionals)
- Lesson 1729 — Identifying Hot Types in Traces
- Cross-environment (`globalThis`)
- Lesson 1174 — Augmenting Built-in Global Interfaces
- Cross-reference instantiation counts
- If a type is instantiated 10,000 times, look for places in tight loops or heavily-called functions where that type appears.
- Lesson 1733 — Correlating Trace Data with Code
- Cryptic when errors occur
- Type errors in HKT-heavy code produce sprawling error messages that reference abstract type machinery rather than concrete business logic
- Lesson 1503 — The Complexity Tax of HKT Simulation
- CSS imports
- , **global type augmentations** all need regular imports to execute.
- Lesson 1107 — Type-Only Imports with Side Effects
- CSS Modules
- Lesson 1128 — Wildcard Module Declarations
- Custom Scripts for Counting
- Lesson 1678 — Auditing Codebases for any Usage
D
- Dashboard summary
- Lesson 677 — Pick Use Cases: API Response Subsets
- Data Pipelines
- When data flows through multiple transformation stages, type-driven design ensures each stage's input/output contracts align, preventing runtime shape mismatches.
- Lesson 1333 — When Type-First Design Pays Off
- Data processing loops
- that transform arrays with generic helpers
- Lesson 1724 — Excessive Type Instantiation in Loops
- Data shape mismatches
- If your API expects `{id: number, name: string}` but receives `{userId: number, userName: string}`, TypeScript flags it
- Lesson 8 — API Contract Enforcement
- Data transformation
- where output type depends on input type
- Lesson 1663 — When Generics Are Better: Type Preservation Needed
- Database connections
- Pass your ORM client or connection pool so procedures can query data.
- Lesson 1545 — Context Typing for Procedures
- Database entities
- after creation, when all fields must exist
- Lesson 723 — Making All Properties Required
- Database Schema → TypeScript
- Generate types from SQL table definitions
- Lesson 1514 — Use Code Generation for Complex Patterns
- Debugging clarity
- File names and paths match between source and output
- Lesson 1232 — tsc Output: Per-File Transpilation
- Debugging import errors
- Why can't TypeScript find your module?
- Lesson 1120 — Module Resolution Tracing with --traceResolution
- Debugging requires expertise
- in your own type system's internals rather than domain logic
- Lesson 1506 — Error Messages Become Unusable
- declaration file
- (`.
- Lesson 62 — declaration: Generating .d.ts FilesLesson 1124 — What Are Declaration Files (.d.ts)Lesson 1136 — What Declaration Files Are
- declaration files
- (files ending in `.
- Lesson 59 — skipLibCheck: Faster CompilationLesson 1139 — Declaring Functions
- Declaration Files Are Required
- Lesson 1222 — Enabling composite: true
- Declaration maps
- create a bridge back to the source.
- Lesson 1249 — Declaration Maps for Source Navigation
- declaration merging
- .
- Lesson 361 — Declaration Merging BasicsLesson 367 — Type Aliases Cannot MergeLesson 371 — Declaration Merging: The Key Interface SuperpowerLesson 1161 — Practical Example: Typing process.envLesson 1165 — Adding Properties to Existing InterfacesLesson 1170 — Real-World Example: Augmenting ExpressLesson 1257 — Namespace Exports and LimitationsLesson 1490 — The Lightweight Higher- Kinded Types Trick (+2 more)
- Declaring global libraries
- that attach to `window` or `global`
- Lesson 1143 — Namespaces in Declarations
- Decorator context object
- is now the primary way to access metadata
- Lesson 1784 — Decorator Standardization Progress
- Decorator execution order
- changed (top-to-bottom vs bottom-to-top in some contexts)
- Lesson 1784 — Decorator Standardization Progress
- Decorators
- Lesson 19 — TypeScript 5.x: Modern FeaturesLesson 1769 — Syntax That Would Be Standardized
- Dedicated Slack/Teams channel
- for migration questions
- Lesson 1601 — Team Coordination During Migration
- Dedicated TypeScript CI Bots
- Lesson 1270 — Reporting Type Errors in Pull Requests
- Deep nesting
- Multiple levels of `if`/`else` checking different type guards
- Lesson 1709 — Control Flow Analysis OverheadLesson 1718 — Variadic Tuple Complexity
- Deep recursion errors
- or "Type instantiation is excessively deep"
- Lesson 1448 — Performance Considerations with Complex infer
- Deep type recursion
- creates nested structures your IDE expands fully
- Lesson 1484 — Recognizing When You've Gone Too FarLesson 1631 — Build Times Exploding
- Deeply nested generics
- where type parameters flow through many layers
- Lesson 1717 — The Hidden Cost of InferenceLesson 1749 — Complex Types and Autocomplete Lag
- Deeply nested routers
- with many layers can exceed TypeScript's recursion limits.
- Lesson 1580 — Type Inference Limitations and Workarounds
- DeepPartial pattern
- uses conditional types to detect object types and recursively apply the transformation:
- Lesson 812 — The DeepPartial Pattern
- Default behavior is acceptable
- A catch-all `else` or `default` case handles all other variants identically
- Lesson 426 — When Exhaustiveness Isn't Needed
- Default Behavior Is Intentional
- Lesson 963 — When to Skip Exhaustiveness Checks
- Default to string enums
- for most application code — clarity beats brevity.
- Lesson 498 — When to Choose Numeric vs String Enums
- default values
- that kick in when a property is missing or `undefined`.
- Lesson 309 — Default Values with Optional PropertiesLesson 1056 — Static Properties Basics
- Defensive library APIs
- that return deeply frozen data structures
- Lesson 813 — The DeepReadonly Pattern
- Deferred resolution
- when type parameters are involved and not yet known
- Lesson 776 — When Conditionals Resolve
- Define a schema
- that matches your API expectations (using Zod, Yup, etc.
- Lesson 1317 — Type Safety in Form Handling
- Define the type
- What shape should this function accept?
- Lesson 1328 — Using Types to Drive Implementation
- Definite assertion `!`
- Property type is `string` — you promise it will be assigned, just not in a way TypeScript can verify
- Lesson 1022 — Optional Properties in Classes
- DefinitelyTyped
- .
- Lesson 34 — TypeScript in Package EcosystemsLesson 165 — Inference with Third-Party LibrariesLesson 1131 — DefinitelyTyped and @types Packages
- Delayed autocomplete
- several-second pauses before suggestions appear
- Lesson 1505 — IDE Performance Degradation
- Delayed error highlighting
- Red squiggles appearing seconds after you type
- Lesson 1477 — Compile-Time Performance Impact
- Delayed resolution
- Lesson 591 — Generic Promise Wrappers
- Deno
- , created by Node.
- Lesson 33 — Backend TypeScript: Node.js and BeyondLesson 1792 — Ecosystem Integration: Bundlers and Runtimes
- Deno or Bun
- , which run TypeScript natively without configuration.
- Lesson 75 — Choosing the Right Execution Method for Your Use Case
- Dependencies
- `node_modules` (usually excluded by default, but explicit is better).
- Lesson 1751 — excludeFiles and IDE Performance
- Dependency count
- – Each package in `node_modules` (especially with type definitions) adds more types to resolve
- Lesson 1750 — Project Size Impact on IDE Speed
- Dependency injection
- where properties are set by a container
- Lesson 1021 — Definite Assignment Assertion (!)
- Deprecate with comments
- Add `@deprecated` JSDoc comments to the old types to guide developers:
- Lesson 1660 — Incremental Refactoring Strategy
- Deprecated API bridges
- When supporting old code paths you're actively removing.
- Lesson 896 — When @ts-expect-error Is Preferred
- Deprecation is extremely rare
- TypeScript almost never deprecates features.
- Lesson 1794 — Backwards Compatibility Commitment
- Deprecation Warnings
- When possible, features are deprecated with compile-time warnings before removal.
- Lesson 1785 — Community Feedback and Breaking Changes
- Describe the Domain Concept
- Lesson 1659 — Naming Conventions for Focused Types
- Describing global functions
- Lesson 1129 — The declare Keyword
- Describing global variables
- Lesson 1129 — The declare Keyword
- Design Meetings
- Notes from weekly design meetings are published publicly, showing the reasoning behind decisions.
- Lesson 1785 — Community Feedback and Breaking ChangesLesson 1793 — The Role of Community Feedback
- Destructured values without context
- The structure doesn't tell TypeScript what types are inside
- Lesson 1200 — noImplicitAny: Banning Implicit any Types
- Detailed Release Notes
- Breaking changes get their own section with migration guidance.
- Lesson 1785 — Community Feedback and Breaking Changes
- Determines the dependency graph
- which projects depend on which
- Lesson 1224 — Building with --build Mode
- Developer Surveys
- Lesson 31 — TypeScript Adoption in the Industry
- Development halts
- during migration—no new features, no bug fixes, just type errors.
- Lesson 1613 — The All-at-Once Approach: Risks and Rewards
- Development mode
- where speed matters more than exhaustive checking
- Lesson 59 — skipLibCheck: Faster Compilation
- Development workflows
- where you're iterating frequently
- Lesson 1746 — Use Incremental Compilation and Build Modes
- Different `moduleResolution` strategies
- between environments
- Lesson 1123 — Troubleshooting Common Resolution Errors
- different types
- based on input types
- Lesson 279 — Real-World Overload ExamplesLesson 331 — Property Override Order and Type Merging
- Difficult narrowing
- When you need to narrow a giant union, your switch statements or if-else chains become massive.
- Lesson 1651 — The Readability Problem with Giant Union TypesLesson 1653 — Discriminated Unions vs Flat String Unions
- Difficult to debug
- There's no straightforward way to "step through" type-level computation
- Lesson 1503 — The Complexity Tax of HKT Simulation
- Diminishing returns
- The jump from `any` to basic types is huge.
- Lesson 1481 — Simple Types with Good TestsLesson 1494 — The TC39 and TypeScript Roadmap on HKTs
- Direct mismatches are caught
- `UserId` can't directly become `ProductId`
- Lesson 1357 — Flavoring vs Full Branding
- Direct operations preserve labels
- Lesson 1401 — Consistency Across Tuple Operations
- Directly exposed
- (naked): Apply the conditional to each union member separately
- Lesson 779 — What Makes a Conditional Type Distributive
- Disadvantages
- More invasive changes, higher risk of incorrect inferences, requires more careful review, and runs slower than ts-migrate's quick-fix approach.
- Lesson 1647 — Alternative Tools: TypeStat
- discriminant
- or **tag**) is a common property that exists on all union members, where each member has a different literal value for that property.
- Lesson 399 — Narrowing with Discriminant PropertiesLesson 411 — Result Types with Discriminated UnionsLesson 613 — Result/Either Type for Error Handling
- discriminant property
- is a unique property that exists on one union member but not others (or has a unique literal value).
- Lesson 226 — Type Predicates for Union NarrowingLesson 399 — Narrowing with Discriminant PropertiesLesson 405 — The Discriminant PropertyLesson 1653 — Discriminated Unions vs Flat String Unions
- discriminated union
- (also called a "tagged union") is a union of object types where each variant has a common property with a distinct literal value.
- Lesson 404 — What Is a Discriminated Union?Lesson 406 — Basic Discriminated Union Example
- discriminated unions
- are pure type-level constructs that compile away completely.
- Lesson 414 — Discriminated Unions vs EnumsLesson 652 — When Conditional Constraints Become Too ComplexLesson 1292 — Union and Discriminated Union SchemasLesson 1336 — Discriminated Unions for StateLesson 1414 — What const Type Parameters SolveLesson 1433 — When Builders Add vs Remove Value
- distributes
- the mapping across each union member:
- Lesson 733 — Creating Option Types from UnionsLesson 769 — Conditional Types with Union InputLesson 780 — Distributive Behavior with Union TypesLesson 819 — Basic Template Literal SyntaxLesson 1445 — Union Distribution Through infer
- Distribution magic
- When `T` is a union, this distributes over each member
- Lesson 974 — Building NonNullable with never
- distributive conditional types
- .
- Lesson 784 — The Extract Utility Type ExplainedLesson 972 — Building Exclude with neverLesson 973 — Building Extract with never
- Document with simple examples
- , not type signatures
- Lesson 1482 — Library Boundaries and Type Complexity
- Document your extensions
- future developers need to know these aren't standard library features
- Lesson 365 — Augmenting Third-Party Interfaces
- documentation
- and **guardrails**.
- Lesson 92 — Type Annotations for PrimitivesLesson 244 — Explicitly Typing Callback ParametersLesson 447 — Intersection Order IndependenceLesson 1032 — public: The Default VisibilityLesson 1398 — Labels in Function SignaturesLesson 1652 — Breaking Down Large Unions into Semantic Groups
- Documentation generators
- that extract type information
- Lesson 1796 — Long-Term Vision: TypeScript as a Platform
- Documentation rots quickly
- as type implementations evolve
- Lesson 1480 — The Maintenance Burden of Clever Types
- Doesn't show intermediate steps
- you can't see which specific `infer` failed
- Lesson 1476 — Debugging Complex Type Errors
- Domain Concepts Are Non-Interchangeable
- Lesson 1369 — When Opaque Types Add Value
- Domain modeling is complex
- Financial systems, medical records, or state machines benefit from explicit type modeling before implementation
- Lesson 1326 — Type-First vs Code-First Trade-offs
- Domain models
- used everywhere (User, Product, Order)
- Lesson 1156 — Declaring Global Types and Interfaces
- double assertion
- Lesson 992 — Understanding Double AssertionsLesson 995 — Overriding Incompatible Types
- Dynamic property access
- Code using `obj[dynamicKey]` patterns needs index signatures or refactoring
- Lesson 1594 — The .js to .ts Rename Strategy
- Dynamic typing
- means types are checked *while* the program is running.
- Lesson 1 — What is Static Typing?
E
- Easier maintenance
- Add a union member once, not across multiple overloads
- Lesson 1408 — Union Signatures for Shared Logic
- Easier refactoring
- Change a value once, and the inferred type updates everywhere automatically
- Lesson 155 — The Default Rule: Let TypeScript Infer
- Ecosystem compatibility
- Built-in support for JavaScript libraries through DefinitelyTyped
- Lesson 23 — Flow: Facebook's Type Checker
- Effect
- , and **ts-results** have invested thousands of hours solving the edge cases, performance issues, and ergonomic problems you'll hit when building advanced patterns yourself.
- Lesson 1510 — Use Libraries with Good Types Instead of Recreating Them
- either
- `null` **or** `undefined`, and `false` for everything else.
- Lesson 203 — Loose Equality == null PatternLesson 594 — Generic Result/Either TypesLesson 613 — Result/Either Type for Error Handling
- Empty array initialization
- Lesson 602 — Inference Failure Cases
- Empty arrays
- Lesson 600 — Explicit Type Arguments with Angle BracketsLesson 1466 — Base Cases and Termination Conditions
- Empty collection edge cases
- Instead of `items: T[]` that might be empty when it shouldn't be, use `{ status: 'empty' } | { status: 'populated'; items: [T, .
- Lesson 1346 — Refactoring Toward Impossible States
- Encapsulate business logic
- around property changes
- Lesson 1041 — Getters and Setters with Different Access
- Encapsulation
- Package internals stay private; only documented paths work
- Lesson 1116 — The exports Field for Modern Packages
- Encode
- (serialize) TypeScript values back to a wire format
- Lesson 1302 — io-ts and Codec-Based Inference
- enforce
- requirements.
- Lesson 229 — Assertion Functions BasicsLesson 230 — Simple Assertion Function SyntaxLesson 261 — Typing Rest Parameters ExplicitlyLesson 751 — Preserving vs Overriding: When to Use +Lesson 1567 — Client-Side Query and Mutation Hooks
- Enforced boundaries
- Can't accidentally import from `admin-app` into `customer-portal`
- Lesson 1229 — Monorepo Patterns with References
- enforces
- that you can't accidentally use the imported name as a value.
- Lesson 1103 — The import type SyntaxLesson 1323 — Types as Specifications
- Enums
- create actual JavaScript objects at runtime (in most cases), while **discriminated unions** are pure type-level constructs that compile away completely.
- Lesson 414 — Discriminated Unions vs EnumsLesson 481 — Literal Unions vs Enums: Trade-offsLesson 1769 — Syntax That Would Be Standardized
- Enums are different
- Lesson 507 — Enums Generate Runtime Code
- Erasable
- Can be completely removed without changing runtime behavior
- Lesson 1769 — Syntax That Would Be Standardized
- Error case
- `{ success: false, error: ZodError }` — detailed error information
- Lesson 1294 — Safe Parsing with .safeParse
- Error detection
- Typos and wrong method calls slip through
- Lesson 179 — Implicit any from Untyped Parameters
- Error localization
- Pinpoint exactly which step breaks the chain
- Lesson 1759 — Pipeline Operator and Type Flow
- error messages
- when properties conflict, because TypeScript recognizes the hierarchical intent.
- Lesson 432 — Intersection vs ExtensionLesson 447 — Intersection Order IndependenceLesson 1489 — TypeScript's Workaround: Interface PatternLesson 1518 — Typing Component Props with Interfaces
- Error messages become cryptic
- when deeply nested types fail
- Lesson 1480 — The Maintenance Burden of Clever TypesLesson 1510 — Use Libraries with Good Types Instead of Recreating ThemLesson 1689 — What 'Clever' Means in TypeScript
- Error messages become incomprehensible
- When a type fails to match, the compiler might generate a 200-line error message showing the entire recursive expansion.
- Lesson 1475 — The Readability Cost of Complex Type-Level CodeLesson 1508 — Diminishing Returns on Type Safety
- Error-safe wrappers
- Lesson 591 — Generic Promise Wrappers
- ES2015
- (or ES6): Modern baseline (arrow functions, classes)
- Lesson 52 — target: Choosing Your Output JavaScript Version
- ES2020
- Recent features (optional chaining, nullish coalescing)
- Lesson 52 — target: Choosing Your Output JavaScript Version
- ES2020+
- Modern features like optional chaining
- Lesson 78 — The --target Flag: Choosing Your JavaScript Version
- ES5
- Maximum compatibility (IE11, very old browsers)
- Lesson 52 — target: Choosing Your Output JavaScript VersionLesson 78 — The --target Flag: Choosing Your JavaScript Version
- ES6/ES2015
- Classes, arrow functions, promises
- Lesson 78 — The --target Flag: Choosing Your JavaScript Version
- esbuild
- , and **swc** have TypeScript compilation built directly into their bundling process.
- Lesson 35 — Build Tools and TypeScriptLesson 67 — tsx: A Faster Alternative to ts-nodeLesson 1234 — Bundlers: Webpack, Rollup, esbuild, and OthersLesson 1238 — esbuild and swc: Fast Type StrippingLesson 1241 — Vite and Modern Bundler WorkflowsLesson 1242 — Source Maps Across ToolsLesson 1253 — What isolatedModules DoesLesson 1258 — When to Enable isolatedModules (+1 more)
- ESM
- (ECMAScript Modules, the standardized version).
- Lesson 1121 — ESM vs CommonJS Resolution Differences
- ESNext
- Absolute latest JavaScript proposals
- Lesson 52 — target: Choosing Your Output JavaScript VersionLesson 78 — The --target Flag: Choosing Your JavaScript Version
- every possible combination
- of strings by computing the cartesian product.
- Lesson 821 — Template Literals with Union TypesLesson 828 — Limitations of Template LiteralsLesson 1716 — String Template Literal Type Explosion
- every property
- from each component type.
- Lesson 429 — What is an Intersection Type?Lesson 1044 — The implements Keyword
- everything
- .
- Lesson 438 — Reading Intersection Error MessagesLesson 912 — The Problem: unknown Blocks Everything
- Exact string literals
- for type safety (like configuration keys)
- Lesson 1416 — const vs Normal Type Parameters
- exactly
- how many elements there are and what type each position holds.
- Lesson 114 — Fixed-Length Arrays vs TuplesLesson 271 — Simple Overload ExampleLesson 1770 — What Gets Ignored vs What Gets Parsed
- Example distinction
- Lesson 267 — Rest Parameters vs Array Parameters
- Example pattern
- Lesson 419 — What Exhaustive Matching Means
- Example situation
- You install a popular JavaScript utility library, but TypeScript treats all its exports as `any` because there's no type information available.
- Lesson 1125 — When You Need Declaration Files
- excess property checks
- .
- Lesson 322 — What Are Excess Property ChecksLesson 324 — Fresh vs Non-Fresh Objects
- Exclude
- removes types from `T` that are assignable to `U` (keeps what doesn't match)
- Lesson 691 — Exclude vs Extract Mental ModelLesson 977 — never vs undefined in Conditionals
- Execute Program
- , **TypeScript Exercises**, and **type-challenges** on GitHub offer progressively harder problems.
- Lesson 39 — Community Resources and Learning
- exhaustiveness checking
- making sure you haven't forgotten any possibilities.
- Lesson 206 — Switch Statement ExhaustivenessLesson 466 — When to Use Literal TypesLesson 682 — Record with String Literal KeysLesson 685 — Record vs Index SignaturesLesson 947 — Empty Union Resolution
- expand
- these types immediately (computing all possibilities), or should it **defer** expansion (keeping the types lazy)?
- Lesson 1708 — Union and Intersection ExpansionLesson 1749 — Complex Types and Autocomplete Lag
- Experimental decorators
- (`experimentalDecorators: true`) — the original implementation most libraries still use
- Lesson 1757 — Decorators: The Long Journey
- explicit
- , it's a conscious decision to abandon type safety for that specific value—useful in the narrow cases you've learned, but dangerous when overused.
- Lesson 876 — any Disables All Type CheckingLesson 1080 — this Return Types vs Explicit Class NamesLesson 1259 — verbatimModuleSyntax as Stricter Alternative
- Explicit `this` parameters
- A fake first parameter that declares what `this` should be
- Lesson 1089 — ThisType vs Explicit this Parameters
- Explicit `this` parameters are
- Lesson 1089 — ThisType vs Explicit this Parameters
- explicit and type-safe
- .
- Lesson 411 — Result Types with Discriminated UnionsLesson 613 — Result/Either Type for Error Handling
- Explicit annotation
- means writing out the TypeScript type first, then building a schema that matches it.
- Lesson 1309 — When to Explicitly Annotate vs Purely Infer
- Explicit return type
- Better for documentation, shows intent clearly
- Lesson 1523 — Typing Custom Hooks with Return Tuples
- explicit type arguments
- using angle brackets right after the function name:
- Lesson 533 — Explicit Type ArgumentsLesson 542 — Explicit Type ArgumentsLesson 600 — Explicit Type Arguments with Angle Brackets
- Explicitness prevents errors
- You want callers to think carefully about the type
- Lesson 570 — When to Use Defaults vs Required Parameters
- Exponential intersection checks
- combining unions multiplies complexity
- Lesson 1741 — Break Large Union Types into Smaller Chunks
- Export simple interface wrappers
- instead of raw conditional types
- Lesson 1482 — Library Boundaries and Type Complexity
- Express
- remains the most popular Node.
- Lesson 33 — Backend TypeScript: Node.js and BeyondLesson 1540 — Framework Comparison: Where Types Come From
- Express: Manual Typing
- You define everything yourself through generics.
- Lesson 1540 — Framework Comparison: Where Types Come From
- extend
- it using intersections.
- Lesson 450 — Extending Base Types with CapabilitiesLesson 621 — What extends Does in Generic Constraints
- extends
- (is assignable to) `TypeToMatch` gets included in the result.
- Lesson 695 — Extract for Type-Safe SubsetsLesson 768 — Conditional Types with Primitives
- External API responses
- Lesson 1676 — Replacing any with unknown for Safe Migration
- External data
- (API responses, user input, configuration files)
- Lesson 1509 — Embrace Runtime Checks Over Type Gymnastics
- External library integration
- Use `any` temporarily for untyped third-party code
- Lesson 874 — Gradual Typing Philosophy
- External library types
- Missing `@types` packages you can install
- Lesson 1678 — Auditing Codebases for any Usage
- Extract
- keeps only types from `T` that are assignable to `U` (keeps what does match)
- Lesson 691 — Exclude vs Extract Mental ModelLesson 707 — When These Utilities Save RepetitionLesson 1435 — Basic infer Pattern: Extracting Array Element Types
- Extract complex conditionals
- into separate type aliases
- Lesson 650 — Error Messages from Failed Conditional Constraints
- Extract constraint types
- Lesson 1740 — Limit Generic Constraint Complexity
- Extract intermediate types
- Instead of chaining operations inline, break them into named type aliases you can inspect individually.
- Lesson 1691 — Debugging Complex Generic Errors
- Extract shared code
- Move code both projects need into a third, lower-level project that both can reference
- Lesson 1228 — Circular References Between Projects
- Extracting intermediate types
- instead of nesting everything inline
- Lesson 764 — Performance Considerations with as
F
- Factory patterns
- `ConstructorParameters<typeof MyClass>` lets you build helpers without retyping constructor args
- Lesson 707 — When These Utilities Save Repetition
- Fail loudly
- The `throw` ensures bad data never leaks through
- Lesson 934 — Generic parseResponse Helper Function
- Falls back gracefully
- if no match, resolution fails (no default file crawling)
- Lesson 1116 — The exports Field for Modern Packages
- false positives
- cases where TypeScript narrows the type based on your predicate, but the actual runtime value doesn't match.
- Lesson 235 — Type Predicate and Assertion PitfallsLesson 1190 — The Cost of strict: False Positives
- Fast development iteration
- Running scripts repeatedly during development
- Lesson 67 — tsx: A Faster Alternative to ts-node
- Fast JavaScript transpilation
- (bundlers' strength)
- Lesson 1247 — Setting emitDeclarationOnly in tsconfig.json
- Fast scenarios
- Lesson 1707 — Contextual Typing Performance
- Fast transpilation
- (bundler): `vite build` or `esbuild src/index.
- Lesson 1235 — Type-Checking vs Transpilation Separation
- Faster builds
- TypeScript doesn't need to re-parse and re-check all source files from referenced projects
- Lesson 1227 — Cross-Project Imports
- Faster development
- You spend less time writing redundant type information
- Lesson 155 — The Default Rule: Let TypeScript Infer
- Faster editor feedback
- Your IDE can parse and bind code instantly while deferring expensive type checks
- Lesson 1699 — TypeScript's Two-Phase Compilation Model
- Faster feedback loops
- Change code, refresh browser.
- Lesson 1768 — The Motivation: Types Without Transpilation
- Faster iteration
- No need to clone locally and run type-checks to understand CI failures
- Lesson 1270 — Reporting Type Errors in Pull Requests
- Fastify
- offers high-performance HTTP handling with first-class TypeScript support.
- Lesson 33 — Backend TypeScript: Node.js and BeyondLesson 1540 — Framework Comparison: Where Types Come From
- Fastify: Schema-Driven Approach
- You define JSON schemas, and TypeScript types are derived from those schemas (or vice versa with type providers).
- Lesson 1540 — Framework Comparison: Where Types Come From
- Fewer contradictions
- You can't accidentally write an annotation that conflicts with the actual value
- Lesson 155 — The Default Rule: Let TypeScript Infer
- Fewer escape hatches
- TypeScript's `any` type essentially turns off type checking.
- Lesson 27 — Hegel: A Stronger Type System for JavaScript
- File-level bottlenecks
- Specific files that dominate check time
- Lesson 1754 — Measuring IDE Performance
- Files processed
- How many files TypeScript examined
- Lesson 1731 — The --diagnostics Flag for Quick Summaries
- filter
- or **branch** based on type
- Lesson 233 — Assertion Functions vs Type PredicatesLesson 970 — never as the Empty Type in ConditionalsLesson 977 — never vs undefined in Conditionals
- Filter by property presence
- Lesson 810 — Filtering Union Members by Shape
- Find type errors gradually
- without project-wide disruption
- Lesson 1606 — The @ts-check Directive for File-Level Opt-In
- first
- in overload resolution order—TypeScript checks them from most-recently-declared to earliest.
- Lesson 363 — Merging Function Overloads in InterfacesLesson 749 — Modifier Precedence and Ordering
- First assertion
- (`as unknown`): Any type can be asserted to `unknown` (the top type)
- Lesson 995 — Overriding Incompatible Types
- First assertion (`as unknown`)
- You tell TypeScript "forget what this value is—treat it as completely unknown"
- Lesson 994 — The unknown Middle Step
- First pass
- You might define a simple interface based on requirements:
- Lesson 1329 — Refining Types Through Iteration
- Fix
- Check your import path matches the actual file location.
- Lesson 1123 — Troubleshooting Common Resolution Errors
- fixed-length
- tuple, you must be explicit with a type annotation or use `as const`:
- Lesson 151 — Tuple Inference vs Array InferenceLesson 1370 — Tuple Types vs Array Types
- Fixing ambiguous inference
- Lesson 606 — Overriding Inferred Types
- flexibility
- .
- Lesson 146 — Widening: From Literal to Broader TypesLesson 1104 — Mixed Imports: Types and Values
- Follow the errors
- Let compiler errors tell you what's missing
- Lesson 1328 — Using Types to Drive Implementation
- Following best practices
- Most modern TypeScript projects prefer explicit imports over globals.
- Lesson 1159 — export {} to Force Module Context
- Follows subpath patterns
- matches wildcards like `".
- Lesson 1116 — The exports Field for Modern Packages
- For library compatibility
- , some older packages may struggle with certain strict checks.
- Lesson 1193 — strict vs Individual Flags
- For Node.js projects
- Use `"moduleResolution": "node16"` or `"nodenext"`
- Lesson 1626 — Module Resolution Confusion
- For types + operations
- Lesson 1587 — Configuring GraphQL Codegen
- For types only
- Lesson 1587 — Configuring GraphQL Codegen
- forces
- you to check for errors before accessing the value.
- Lesson 613 — Result/Either Type for Error HandlingLesson 1196 — strictNullChecks: Preventing Null and Undefined ErrorsLesson 1340 — Payment State Modeling
- Forcing wider types
- Lesson 600 — Explicit Type Arguments with Angle Brackets
- Form 1: `asserts condition`
- Lesson 229 — Assertion Functions Basics
- Form Handling
- Exclude auto-generated fields when creating new records:
- Lesson 678 — Omit<T, K>: Excluding Properties
- Form Submissions
- Lesson 1524 — Event Handler Typing: onClick, onChange, onSubmit
- Forward mapping
- from name to value (like a normal object)
- Lesson 489 — Reverse Mapping in Numeric Enums
- Fragile coupling
- Changes to business logic require navigating type-level complexity
- Lesson 1515 — Separate Business Logic from Type Acrobatics
- Framework extensions
- Adding methods to jQuery objects or Express request objects
- Lesson 1629 — Prototype Manipulation and Monkey-Patching
- Framework lifecycle methods
- (like React's `componentDidMount`)
- Lesson 1021 — Definite Assignment Assertion (!)
- Frequent re-exports
- Each re-export chain requires additional resolution hops
- Lesson 1710 — Symbol Table Lookups and Resolution
- From Schema to Types
- The tool analyzes your GraphQL schema file (or introspects a running GraphQL server) and generates TypeScript type definitions for every type, query, mutation, and subscription defined in your schema.
- Lesson 1586 — GraphQL Code Generator Overview
- Frontend developers
- can build components using the agreed-upon data structures, even if the API isn't finished yet
- Lesson 1332 — Collaborating Through Type Definitions
- Full autocomplete
- Your editor knows exactly what data to send and what you'll receive back
- Lesson 1541 — tRPC Procedure BasicsLesson 1575 — Context Type Propagation
- Function boundaries
- Passing narrowed types through many function calls
- Lesson 1709 — Control Flow Analysis Overhead
- Function introspection
- (ReturnType, Parameters, ConstructorParameters, InstanceType, ThisParameterType, OmitThisParameter)
- Lesson 716 — The Full Standard Library Reference
- Function overloads
- let you declare multiple *signatures* (the parameter and return type patterns) for a single *implementation* (the actual function body).
- Lesson 268 — What Are Function Overloads?Lesson 277 — Overloads vs Conditional TypesLesson 387 — Unions vs OverloadsLesson 652 — When Conditional Constraints Become Too ComplexLesson 662 — When Constraint Composition Becomes OverengineeringLesson 1404 — What Function Overloads AreLesson 1406 — Union Signatures as an AlternativeLesson 1668 — Overloads vs Generic Union Parameters
- Function parameters
- that are exported
- Lesson 160 — Inference Across Module BoundariesLesson 198 — typeof Guards in PracticeLesson 1181 — noImplicitAny ExplainedLesson 1672 — Implicit any from Missing Type Annotations
- Function parameters without annotations
- Lesson 127 — When any Appears by Default
- Function parameters without types
- TypeScript has no context to infer what arguments you'll pass
- Lesson 1200 — noImplicitAny: Banning Implicit any Types
- Function properties
- (`propertyName: () => ReturnType`) describe properties that *happen* to hold functions.
- Lesson 293 — Method Shorthand vs Function Properties
- Function return types
- A library returns `any`, so you don't know what you're getting
- Lesson 884 — any in Third-Party Libraries
- Function signatures
- showing parameters and return types
- Lesson 1138 — Basic Declaration File Structure
- Function type expressions
- let you define a function's shape once and reuse it everywhere through a type alias.
- Lesson 240 — Function Type Expressions
- Functions that never return
- Lesson 134 — Introduction to never: The Bottom Type
- Functor
- abstraction is impossible to express directly in TypeScript because it requires abstracting over the container type itself (`Maybe`, `Array`, `Either`) rather than just the contained value.
- Lesson 1488 — Languages That Have HKTsLesson 1498 — Encoding Functors with HKT Simulation
- Future maintainers understand context
- without archaeological code digging
- Lesson 901 — Linting Suppression Comments
- Future-proof code
- You can use cutting-edge features knowing they'll become standard JavaScript
- Lesson 22 — TypeScript's Relationship with TC39
G
- Gather constraints
- `T` must match the type of `"hello"`, `U` must match the type of `42`
- Lesson 1702 — Constraint Solving and Unification
- Generated code
- If you have code generation steps, exclude the output folders.
- Lesson 1751 — excludeFiles and IDE Performance
- Generic `<T>`
- The function doesn't care what type you're validating—it adapts
- Lesson 934 — Generic parseResponse Helper Function
- Generic cache utilities
- use type parameters to capture the exact signature of the function being cached—ensuring TypeScript knows what arguments are valid and what type the result will be.
- Lesson 598 — Generic Cache and Memoization
- generic classes
- let you define type parameters that can be used throughout the class body—in constructor parameters, instance properties, and methods.
- Lesson 552 — Generic Classes: Constructor and PropertiesLesson 562 — When to Use Generic Classes vs Functions
- Generic conditional types
- are dynamic: you write a single signature with a type that branches based on generic type parameters.
- Lesson 277 — Overloads vs Conditional Types
- Generic constraints
- Poorly-typed generics that fall back to `any`
- Lesson 884 — any in Third-Party LibrariesLesson 1503 — The Complexity Tax of HKT Simulation
- Generic constraints without hints
- When you use a generic function, TypeScript may not have enough information to infer the parameter types inside unless you provide explicit type arguments.
- Lesson 188 — Contextual Typing Not Applied Everywhere
- generic function
- is a function that uses type parameters to work with different types while preserving full type information.
- Lesson 537 — What Are Generic Functions?Lesson 538 — Your First Generic FunctionLesson 1520 — Typing useState with Generic Type Arguments
- Generic functions
- are best for stateless, single operations that transform or process data
- Lesson 562 — When to Use Generic Classes vs Functions
- Generic instantiations
- The result of applying type arguments to generic types
- Lesson 1704 — The Type Cache and Memoization
- Generic parameters
- say "Tell me *exactly* what type you're passing, and I'll remember it throughout the function.
- Lesson 1665 — Unions Widen, Generics Narrow
- Generic preservation
- Less type widening through transformation chains
- Lesson 1759 — Pipeline Operator and Type Flow
- Generic procedures
- that depend on runtime values sometimes can't be fully inferred statically.
- Lesson 1580 — Type Inference Limitations and Workarounds
- Generic refinement
- (each method narrows the type parameter)
- Lesson 612 — Builder Pattern with Fluent Generics
- Generic syntax
- `Array<number>`, `function identity<T>(x: T)`
- Lesson 1769 — Syntax That Would Be Standardized
- generic type parameters
- and **`keyof` constraints**.
- Lesson 635 — The Classic Property Getter PatternLesson 1529 — Request and Response Types in Express
- Generic union parameters
- use a single signature with a type parameter constrained to a union.
- Lesson 1668 — Overloads vs Generic Union Parameters
- generics
- , TypeScript tries to infer what `<T>` should be based on how you use a function.
- Lesson 187 — Generic Inference Falling Back to UnknownLesson 550 — Generic Functions vs Function OverloadsLesson 1537 — Fastify Request and Reply GenericsLesson 1670 — The Readability Trade-off
- Gets Ignored
- The engine does absolutely nothing with the type information—no checking, no enforcement, no runtime behavior
- Lesson 1770 — What Gets Ignored vs What Gets Parsed
- Gets Parsed
- The engine recognizes type annotation syntax and validates it's structurally correct
- Lesson 1770 — What Gets Ignored vs What Gets Parsed
- GitHub Actions with reviewdog
- Lesson 1270 — Reporting Type Errors in Pull Requests
- GitHub Discussions
- on the TypeScript repo for feature discussions
- Lesson 39 — Community Resources and Learning
- GitHub Issues and Discussions
- Developers report bugs, request features, and debate design decisions in the open.
- Lesson 1785 — Community Feedback and Breaking Changes
- global
- (available everywhere on your machine) or **local** (only within a specific project folder).
- Lesson 41 — Installing TypeScript Globally vs LocallyLesson 1158 — The global Scope in .d.ts FilesLesson 1159 — export {} to Force Module Context
- Global augmentation
- affects everything everywhere:
- Lesson 1179 — Avoiding Global PollutionLesson 1629 — Prototype Manipulation and Monkey-Patching
- Global browser APIs
- added by a third-party library
- Lesson 1150 — What declare Does: Ambient Declarations
- Global Scripts
- Lesson 1125 — When You Need Declaration Files
- Go-to-definition
- navigation
- Lesson 36 — Editor Support and Language ServicesLesson 1642 — Validating JSDoc Coverage with Tooling
- Go-to-definition navigation
- Lesson 1747 — Why IDE Performance Matters
- Good practice
- Document *why* you added global types with comments explaining the necessity.
- Lesson 1179 — Avoiding Global Pollution
- gradual adoption
- you can add types to your JavaScript code incrementally, file by file, function by function.
- Lesson 11 — The Gradual Typing AdvantageLesson 1486 — Why TypeScript Lacks True HKTs
- Gradual Adoption Path
- Lesson 28 — Why TypeScript Won Adoption
- Gradual fixes
- using JSDoc annotations where needed
- Lesson 1612 — Combining allowJs, checkJs, and Incremental Migration
- Gradual migration
- You can enable strict checking incrementally via compiler options
- Lesson 23 — Flow: Facebook's Type CheckerLesson 894 — What Are Type Suppression CommentsLesson 1603 — allowJs: Mixing JavaScript and TypeScript Files
- Gradual strictness
- You can enable strict mode in typed files while allowing loose checking elsewhere
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- Gradual Typing Advantage
- we learned means you *can* start with JavaScript and add TypeScript later when a project grows —but for truly tiny or temporary work, even that migration might never be worth it.
- Lesson 12 — When Static Typing Isn't Worth It
- GraphQL
- You write schemas in SDL, then run `graphql-codegen` to generate TypeScript types
- Lesson 1555 — No Code Generation Required
- GraphQL → TypeScript
- Generate types from GraphQL schema definitions and queries
- Lesson 1514 — Use Code Generation for Complex Patterns
- GraphQL Codegen
- is the right choice when you've already committed to GraphQL.
- Lesson 1589 — When to Choose Each Approach
- GraphQL with Code Generation
- uses `graphql-codegen` to generate TypeScript types from your GraphQL schema.
- Lesson 1581 — The End-to-End Type Safety Landscape
- GraphQL with codegen
- Generate types from schema (requires GraphQL adoption, still a generation step)
- Lesson 1551 — What tRPC Solves: The Type-Safety Gap
- Greenfield codebases benefit most
- because you're not fighting legacy patterns—just write safe code from day one.
- Lesson 1193 — strict vs Individual Flags
- Greenfield rewrites
- where you're already touching every file make this natural.
- Lesson 1613 — The All-at-Once Approach: Risks and Rewards
- guarantee
- the keys you access actually exist.
- Lesson 637 — Combining keyof with Generics for Object ManipulationLesson 751 — Preserving vs Overriding: When to Use +Lesson 773 — Conditional Types with Generic Constraints
- Guaranteed compatibility
- TypeScript won't teach you syntax that contradicts real JavaScript
- Lesson 22 — TypeScript's Relationship with TC39
- Guaranteed correctness
- If Hegel accepts your code, you have higher confidence it won't crash in those specific ways.
- Lesson 27 — Hegel: A Stronger Type System for JavaScript
- Guided by usage
- You discover which types matter based on actual application flow
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
H
- Hard to read
- Even experienced developers struggle to parse 5+ levels of conditional type nesting
- Lesson 1503 — The Complexity Tax of HKT Simulation
- harder to debug
- than runtime checks
- Lesson 1433 — When Builders Add vs Remove ValueLesson 1483 — The Principle of Least Type Power
- Harder to maintain
- Changes ripple through intricate type dependencies
- Lesson 1483 — The Principle of Least Type Power
- Harder to read
- Others (and future-you) need to mentally parse complex type logic
- Lesson 1483 — The Principle of Least Type Power
- Heavily mapped types
- produce verbose property transformations
- Lesson 1484 — Recognizing When You've Gone Too Far
- Hidden Bugs May Survive
- Lesson 898 — The Danger of Suppression Comments
- High CPU usage
- your editor process consuming significant resources
- Lesson 1505 — IDE Performance Degradation
- High-frequency generic utilities
- called throughout your codebase
- Lesson 1739 — Use Type Parameters Instead of Lookups
- High-frequency usage
- in heavily-used utility functions
- Lesson 1738 — Cache Expensive Mapped Type Results
- High-priority features
- the team commits to investigating or shipping
- Lesson 1778 — The Iteration Plan and GitHub Projects
- High-quality codebases
- maintained by experienced teams should avoid automation.
- Lesson 1649 — When Automation Helps vs Manual Migration
- High-risk
- Business logic assertions hiding real type errors
- Lesson 1017 — Measuring Assertion Debt in Your Codebase
- High-value, low-effort flags
- to enable early:
- Lesson 1207 — Strictness Flags Trade-offs: Safety vs Flexibility
- Higher-kinded type
- Would take *type constructors* as parameters (`Container<Array>` where `Container` works with any single-argument type constructor)
- Lesson 1485 — What Are Higher-Kinded Types?
- Higher-kinded types
- (HKTs) would let you abstract over *these type constructors themselves* as first-class values.
- Lesson 1485 — What Are Higher-Kinded Types?
- higher-order function
- is a function that either takes a function as an argument or returns a function as its result.
- Lesson 586 — Higher-Order FunctionsLesson 1485 — What Are Higher-Kinded Types?
- Highly nested union distributions
- through conditional types
- Lesson 1711 — Understanding Type Instantiation Depth
- HKT simulation
- is TypeScript's workaround for expressing relationships between type constructors themselves— not just between concrete types.
- Lesson 1495 — What HKT Simulation Means in TypeScript
- Hono
- High inference, excellent DX for simple cases, opinionated structure
- Lesson 1540 — Framework Comparison: Where Types Come From
- Hono: Path-Based Inference
- The framework uses literal string types from your route definitions to infer parameter types automatically.
- Lesson 1540 — Framework Comparison: Where Types Come From
- hot code paths
- (called frequently)
- Lesson 1735 — Prefer Type Aliases Over Complex Inline TypesLesson 1741 — Break Large Union Types into Smaller Chunks
- Hot types
- are the types that take the longest to instantiate or check.
- Lesson 1729 — Identifying Hot Types in TracesLesson 1754 — Measuring IDE Performance
- How it works
- Lesson 802 — Building a Deep Readonly with inferLesson 811 — Creating Type Guards as TypesLesson 812 — The DeepPartial PatternLesson 813 — The DeepReadonly PatternLesson 853 — Recursive Path Types for Deep ObjectsLesson 1436 — Extracting Function Return TypesLesson 1447 — Building Awaited with infer
- HTTP method mapping
- Mutations typically use POST, queries use GET
- Lesson 1563 — tRPC mutation() Method Basics
I
- I/O operations
- Time spent reading and writing
- Lesson 1725 — Using --extendedDiagnostics for Build MetricsLesson 1726 — Reading the Diagnostics Output
- IDE autocomplete freezes
- while resolving deeply nested conditionals
- Lesson 1509 — Embrace Runtime Checks Over Type Gymnastics
- IDE lag
- autocomplete and hover tooltips slow down dramatically
- Lesson 1741 — Break Large Union Types into Smaller Chunks
- IDE performance degrades
- due to complex type computations
- Lesson 1689 — What 'Clever' Means in TypeScript
- IDE performance suffers
- from poorly optimized custom type-level code
- Lesson 1510 — Use Libraries with Good Types Instead of Recreating Them
- IDE Responsiveness
- The Language Service that powers autocomplete, error squiggles, and quick fixes must remain snappy even in enormous workspaces.
- Lesson 1781 — Performance and Scalability Focus
- Idempotency
- means an operation can be performed multiple times with the same result.
- Lesson 1566 — Idempotency and Query vs Mutation Choice
- Identifiers
- `UserId`, `OrderId`, `ProductId` prevent mixing IDs
- Lesson 1353 — Branding Primitive TypesLesson 1725 — Using --extendedDiagnostics for Build MetricsLesson 1726 — Reading the Diagnostics Output
- identity function
- .
- Lesson 526 — The Identity Function ProblemLesson 590 — The Identity Generic: <T>(x: T) => TLesson 609 — The Identity Function Pattern
- IDEs and editors
- (VS Code, WebStorm, Vim plugins) for autocomplete and error checking
- Lesson 1796 — Long-Term Vision: TypeScript as a Platform
- Image Files
- Lesson 1128 — Wildcard Module Declarations
- Immediate feedback
- on type errors in JavaScript without changing file extensions
- Lesson 1612 — Combining allowJs, checkJs, and Incremental Migration
- Immediate resolution
- when all types involved are concrete/known
- Lesson 776 — When Conditionals Resolve
- Immediate user impact
- Entry points are where bugs hurt most
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- Immediate visibility
- Developers see errors without leaving the PR page
- Lesson 1270 — Reporting Type Errors in Pull Requests
- Immediately after runtime validation
- If you've just verified data with a type guard or validation function, an assertion can bridge the gap when TypeScript can't follow your logic:
- Lesson 1282 — When Type Assertions Are Acceptable
- Immutable
- Once created, a symbol never changes
- Lesson 90 — The symbol TypeLesson 672 — Combining Utility Types
- Immutable configuration objects
- that shouldn't change after initialization
- Lesson 813 — The DeepReadonly Pattern
- Implement
- against the types you've already committed to
- Lesson 1327 — Designing Public APIs with Types
- implementation signature
- with the actual code:
- Lesson 268 — What Are Function Overloads?Lesson 269 — Overload Syntax: Signatures vs ImplementationLesson 272 — The Implementation Signature Must Be CompatibleLesson 1404 — What Function Overloads AreLesson 1409 — Implementation Signature Compatibility
- Implementation signature mismatch
- Lesson 1628 — Function Overload Conflicts
- implicit `any`
- , and it's dangerous because your code *looks* like it's typed but actually has zero type checking on those parameters.
- Lesson 179 — Implicit any from Untyped ParametersLesson 883 — Implicit any from Missing Types
- Implicit `any` everywhere
- Functions without clear parameter patterns will trigger `noImplicitAny` errors
- Lesson 1594 — The .js to .ts Rename Strategy
- Important rules
- Lesson 120 — Optional Tuple Elements
- Importing classes you'll instantiate
- Classes exist at runtime
- Lesson 1109 — Type-Only Import Best Practices
- Impossible refactoring
- Changing a function signature meant manually hunting through thousands of files, hoping you found every usage
- Lesson 14 — The Problem TypeScript Set Out to Solve
- impossible states
- combinations of values that make no sense in your domain but TypeScript happily accepts.
- Lesson 1334 — The Impossible States ProblemLesson 1336 — Discriminated Unions for State
- Impossible type narrowing
- Lesson 134 — Introduction to never: The Bottom Type
- Improved Quick Fixes
- Lesson 1782 — Better Error Messages and Developer Experience
- Improved type inference
- TypeScript gets better at tracking `bigint` vs `number` distinctions
- Lesson 1764 — Numeric Separators and BigInt Evolution
- Improving autocomplete and IntelliSense
- to make the developer experience smoother
- Lesson 15 — TypeScript 0.8 Through 1.0
- In declaration files (`.d.ts`)
- Lesson 1129 — The declare Keyword
- In development
- , Vite uses **esbuild** — an extremely fast transpiler written in Go.
- Lesson 1241 — Vite and Modern Bundler Workflows
- In production
- , Vite switches to **Rollup** for building your final bundle.
- Lesson 1241 — Vite and Modern Bundler Workflows
- In Remix
- , loaders provide similar patterns where you type the data contract between routes and components.
- Lesson 1318 — Type-Safe URL Parameters and Query Strings
- In the constructor
- Lesson 1018 — Basic Class Property TypingLesson 1023 — Readonly PropertiesLesson 1199 — strictPropertyInitialization: Required Class Properties
- In tsconfig.json
- Lesson 1118 — baseUrl and paths for Custom Mappings
- In your tsconfig.json
- Lesson 1642 — Validating JSDoc Coverage with Tooling
- incompatible types
- , interfaces produce a **compile-time error**, while intersections attempt to merge them (often creating `never`):
- Lesson 360 — Interface Extension vs Intersection TypesLesson 439 — Property Type Conflicts in Intersections
- Inconsistent adoption
- Team members might skip writing JSDoc comments
- Lesson 26 — JSDoc Type Annotations in Plain JavaScript
- Increased compilation time
- (minutes instead of seconds)
- Lesson 1715 — Mapped Types Over Large Object Types
- Incremental builds
- TypeScript only rebuilds changed projects and their dependents
- Lesson 1229 — Monorepo Patterns with References
- Incremental compilation
- Changes in one project's internals don't trigger rebuilds in dependent projects unless the API changes
- Lesson 1227 — Cross-Project ImportsLesson 1232 — tsc Output: Per-File TranspilationLesson 1699 — TypeScript's Two-Phase Compilation ModelLesson 1746 — Use Incremental Compilation and Build Modes
- Incremental migration
- .
- Lesson 911 — Migration Strategy: any to unknownLesson 1610 — Declaration Files for JavaScript Libraries
- Incremental rebuild
- (one file changed): 3 seconds
- Lesson 1746 — Use Incremental Compilation and Build Modes
- Incremental safety
- Get type-checking benefits before committing to full TypeScript conversion
- Lesson 1604 — checkJs: Type-Checking JavaScript Without ConversionLesson 1676 — Replacing any with unknown for Safe Migration
- index signature
- looks like `[key: string]: SomeType` and means "this object can have any property name.
- Lesson 219 — in Operator with Index SignaturesLesson 311 — Basic Index Signature SyntaxLesson 318 — Accessing Properties with Index SignaturesLesson 327 — Index Signatures to Allow Extra PropertiesLesson 335 — Index Signatures in Object SpreadsLesson 636 — keyof with Index SignaturesLesson 685 — Record vs Index SignaturesLesson 1206 — noPropertyAccessFromIndexSignature: Explicit Index Access (+1 more)
- index signatures
- those flexible types that accept any string or number key?
- Lesson 219 — in Operator with Index SignaturesLesson 315 — Optional Properties vs Index SignaturesLesson 319 — Index Signatures vs Mapped TypesLesson 729 — Mapped Types vs Index Signatures
- Indirect Property Access
- Lesson 403 — Control Flow Analysis Limitations
- infer
- the boolean type automatically if you initialize the variable with `true` or `false`:
- Lesson 86 — The boolean TypeLesson 94 — Type Inference with PrimitivesLesson 150 — Generic Type Argument InferenceLesson 533 — Explicit Type ArgumentsLesson 601 — Inference from Function ArgumentsLesson 607 — Inference in Generic Class InstantiationLesson 629 — Constraints and Type InferenceLesson 856 — Building URL Builder Functions (+1 more)
- Infer input types
- from Zod schemas you defined server-side
- Lesson 1569 — How tRPC Propagates Types Across the Network Boundary
- Infer return types
- from what your procedures return
- Lesson 1569 — How tRPC Propagates Types Across the Network Boundary
- Inference fails
- The type parameter doesn't appear in function arguments
- Lesson 570 — When to Use Defaults vs Required Parameters
- Inheritance (`extends`)
- The class receives all concrete implementations, properties, and methods from the parent class.
- Lesson 1055 — Combining implements and extends
- Initial assessment
- Turn it on to see how many type errors exist in your JavaScript codebase
- Lesson 1604 — checkJs: Type-Checking JavaScript Without Conversion
- Initialization patterns
- You initialize a value in a callback or method that TypeScript can't trace
- Lesson 985 — Non-Null Assertions with !Lesson 1021 — Definite Assignment Assertion (!)
- Initialize at declaration
- Lesson 1185 — strictPropertyInitialization
- Initialize in the constructor
- Lesson 1185 — strictPropertyInitialization
- Initialized-in-helper patterns
- Lesson 1190 — The Cost of strict: False Positives
- Inline annotations
- (Approach 1) are more common and feel natural.
- Lesson 237 — Arrow Function Type Annotations
- inline comments
- directly on the lines of code that contain type errors.
- Lesson 1270 — Reporting Type Errors in Pull RequestsLesson 1696 — The Documentation Burden
- inlined
- at compile time?
- Lesson 502 — Performance Benefits of const enumsLesson 504 — const enums and isolatedModulesLesson 505 — preserveConstEnums FlagLesson 522 — Bundle Size and Tree-Shaking
- Inner layer
- (uses `T`): ensures the object has the right shape
- Lesson 660 — Constraint Composition in Higher-Order Functions
- Inserts any casts
- where types can be inferred but are problematic
- Lesson 1644 — Running ts-migrate on a Project
- Inside static methods
- Use the class name, or sometimes `this` (which refers to the constructor)
- Lesson 1058 — Accessing Static Members
- Inside the `else` block
- TypeScript knows it must be `number`
- Lesson 189 — What Is Type Narrowing?Lesson 191 — Using typeof to Guard Primitives
- Inside the `if` block
- TypeScript knows it's just `string`
- Lesson 189 — What Is Type Narrowing?Lesson 191 — Using typeof to Guard Primitives
- Installing from @types
- Lesson 1147 — Typing Third-Party Libraries
- Installs dependencies
- using `npm ci` (faster, more reliable than `npm install`)
- Lesson 1265 — Setting Up GitHub Actions for TypeScript
- instances
- of that class.
- Lesson 559 — Static Members in Generic ClassesLesson 1502 — Libraries That Use HKT Simulation: fp-ts
- instantiate
- that type with the concrete type argument.
- Lesson 1711 — Understanding Type Instantiation DepthLesson 1712 — The Cost of Deep Conditional TypesLesson 1724 — Excessive Type Instantiation in Loops
- Instantiations
- How many times generic types were instantiated
- Lesson 1725 — Using --extendedDiagnostics for Build Metrics
- Instead of asserting JSON
- , validate with type predicates:
- Lesson 1013 — Better Alternatives to Common Assertion Patterns
- Instead of non-null assertions
- , use optional chaining or guards:
- Lesson 1013 — Better Alternatives to Common Assertion Patterns
- Integration happens smoothly
- because both sides already conform to the contract
- Lesson 1332 — Collaborating Through Type Definitions
- IntelliSense Enhancements
- Lesson 1782 — Better Error Messages and Developer Experience
- Intent is clear
- Readers see exactly which keys matter
- Lesson 317 — Index Signatures and Record Utility
- interface
- is TypeScript's way of giving a name to an object's shape.
- Lesson 338 — What Interfaces AreLesson 339 — Basic Interface SyntaxLesson 368 — Hybrid Approaches: Interfaces + Type AliasesLesson 1744 — Prefer interface Over type for Object Shapes
- Interface contract (`implements`)
- The class must fulfill the type contract defined by the interface(s).
- Lesson 1055 — Combining implements and extends
- Interface registries
- to map type identifiers to concrete types
- Lesson 1503 — The Complexity Tax of HKT Simulation
- interfaces
- are **named types** — they give a name to a shape, which you can then reference throughout your code.
- Lesson 340 — Interface vs Object Type LiteralLesson 368 — Hybrid Approaches: Interfaces + Type AliasesLesson 1052 — Abstract Classes vs InterfacesLesson 1138 — Basic Declaration File Structure
- Interfacing with Untyped Code
- Lesson 989 — When Assertions Are Legitimate
- Intermediate variables
- If you extract a callback function into a variable before passing it, TypeScript loses context.
- Lesson 188 — Contextual Typing Not Applied Everywhere
- Internal function returns
- Lesson 942 — When NOT to Use unknown
- Internal implementation details last
- less impact on the rest of your codebase
- Lesson 1621 — Dealing with Implicit any in Legacy Code
- Internal microservices
- that benefit from tRPC's zero-config inference
- Lesson 1590 — Hybrid Strategies: Mixing Approaches
- Internal use only
- The enum is used only within a single file or your own codebase, never exported from a library
- Lesson 506 — When to Use const enums
- intersection
- of all possible matches
- Lesson 800 — Union Collapse with Multiple infer SitesLesson 801 — Covariance and Contravariance with inferLesson 1350 — Brand Technique with IntersectionLesson 1444 — Covariance and Contravariance with infer
- intersection type
- merges multiple types together.
- Lesson 354 — Aliasing Intersection TypesLesson 429 — What is an Intersection Type?Lesson 430 — Basic Intersection SyntaxLesson 949 — never in Intersection TypesLesson 1350 — Brand Technique with Intersection
- Intersection Type Conflicts
- Lesson 1631 — Build Times Exploding
- intersection types
- (`&`) and **interface extension** (`extends`).
- Lesson 432 — Intersection vs ExtensionLesson 484 — Combining Literal Unions for Complex States
- Intersections
- perform **structural merging**.
- Lesson 432 — Intersection vs ExtensionLesson 800 — Union Collapse with Multiple infer SitesLesson 801 — Covariance and Contravariance with infer
- Intersections (`&`)
- make optional properties **more required**
- Lesson 442 — Intersection vs Union for Optional Properties
- Introduced as standalone option
- The new flag appears first as its own `tsconfig.
- Lesson 1194 — Future Additions to strict
- Invariants Must Be Maintained
- Lesson 1369 — When Opaque Types Add Value
- Invert the dependency
- Make one project clearly foundational, and move shared interfaces/types there
- Lesson 1228 — Circular References Between Projects
- Investigations
- for experimental features (like those TC39 proposals you learned about)
- Lesson 1778 — The Iteration Plan and GitHub Projects
- io-ts
- comes from the functional programming world and uses a different philosophy:
- Lesson 1295 — Alternatives: Yup, io-ts, ArkTypeLesson 1302 — io-ts and Codec-Based Inference
- Irrelevant errors
- You don't need to fix type errors in code you didn't write
- Lesson 84 — The --skipLibCheck Flag: Skipping node_modules Types
- It reveals developer confusion
- Maybe you didn't realize the function never returns
- Lesson 969 — Unreachable Code After never
- iteration plans
- that outline what the team is working on for each upcoming version.
- Lesson 1778 — The Iteration Plan and GitHub ProjectsLesson 1780 — Features in Active DevelopmentLesson 1785 — Community Feedback and Breaking Changes
- Iteration speed matters most
- Hackathons, proofs-of-concept, or rapid feature validation
- Lesson 1326 — Type-First vs Code-First Trade-offs
J
- January, April, July, October
- rough targets for releases
- Lesson 1777 — Understanding TypeScript's Release Cadence
- JavaScript alignment
- TypeScript's guiding principle is to track JavaScript's evolution.
- Lesson 1494 — The TC39 and TypeScript Roadmap on HKTs
- JavaScript engines will
- Lesson 1771 — Type Checking Still Requires TypeScript
- JavaScript engines will NOT
- Lesson 1771 — Type Checking Still Requires TypeScript
- JavaScript modules
- that haven't been converted yet naturally produce `any` types when imported
- Lesson 868 — Migration Boundaries in Large Codebases
- Jest
- , **Vitest**, and **Playwright** all support TypeScript out of the box or with minimal configuration.
- Lesson 37 — Testing with TypeScript
- JSDoc
- is a commenting system that describes what types functions expect and return.
- Lesson 26 — JSDoc Type Annotations in Plain JavaScript
- JSON Schema → TypeScript
- Convert validation schemas into TypeScript interfaces
- Lesson 1514 — Use Code Generation for Complex Patterns
- Junior developers
- may struggle with generics and union narrowing
- Lesson 1690 — The Readability Trade-off
K
- Keep files as JavaScript
- while gaining type safety
- Lesson 1606 — The @ts-check Directive for File-Level Opt-In
- Keep it generic
- pass type parameters from your subclass to the base class, or even add new ones
- Lesson 558 — Extending Generic Classes
- Keep keys conditionally
- Lesson 757 — Conditional Key Remapping
- Keep projects focused
- Smaller projects mean faster individual checks
- Lesson 1753 — Workspace Recommendations for Speed
- Keep types inline when
- Lesson 1686 — Type Aliases vs Inline Types for Clarity
- Key differences
- Lesson 1784 — Decorator Standardization Progress
- Key insight
- Use `// @ts-expect-error` comments strategically to mark known issues you'll fix later, preventing new violations while cataloging technical debt.
- Lesson 1208 — Combining Strictness Options for Maximum Safety
- key remapping
- (the `as` clause you just learned) with **union iteration**.
- Lesson 758 — Extracting Keys from Union TypesLesson 842 — Prefixing and Suffixing Object Keys
- Key-value pairs
- Lesson 116 — What Tuples Are and When to Use Them
- know
- there's a type error and you're deliberately marking it as a known issue you plan to address.
- Lesson 896 — When @ts-expect-error Is PreferredLesson 1578 — React Query Integration and Inferred Hooks
- Know what procedures exist
- (queries and mutations)
- Lesson 1569 — How tRPC Propagates Types Across the Network Boundary
- Know when to stop
- If your type logic requires 10+ minutes to debug an error message, you've likely exceeded the practical complexity threshold.
- Lesson 1691 — Debugging Complex Generic Errors
- Known regression testing
- When you've identified a type issue but need to deploy a hotfix first.
- Lesson 896 — When @ts-expect-error Is Preferred
L
- label
- .
- Lesson 1213 — allowUnusedLabels: Managing Label UsageLesson 1399 — Optional and Rest Elements with Labels
- Language service optimizations
- for faster IDE interactions
- Lesson 1790 — Performance and Scalability Focus
- Large codebases
- Functions evolve; automated extraction prevents drift
- Lesson 707 — When These Utilities Save RepetitionLesson 1739 — Use Type Parameters Instead of LookupsLesson 1746 — Use Incremental Compilation and Build Modes
- Large discriminated unions
- with dozens of variants force the language service to check each member when providing suggestions.
- Lesson 1749 — Complex Types and Autocomplete Lag
- Large tuple unions
- Spreading over unions of tuples with many elements
- Lesson 1718 — Variadic Tuple Complexity
- Large union types
- generate every possible combination
- Lesson 1484 — Recognizing When You've Gone Too FarLesson 1717 — The Hidden Cost of InferenceLesson 1749 — Complex Types and Autocomplete Lag
- Large-scale code generation
- patterns with generic builders
- Lesson 1724 — Excessive Type Instantiation in Loops
- Lean on IDE hover
- Hover over intermediate variables and type aliases to see what TypeScript inferred before the explosion happened.
- Lesson 1691 — Debugging Complex Generic Errors
- Lean on the compiler
- After removing the old type, TypeScript will surface every location that needs updating—fix them one by one.
- Lesson 1660 — Incremental Refactoring Strategy
- Learning curve
- Your team learns TypeScript patterns organically through real code, not all at once under deadline pressure.
- Lesson 1591 — The Gradual Migration Philosophy
- Learning curve management
- New team members can use `any` as training wheels
- Lesson 874 — Gradual Typing Philosophy
- Learning Foundation
- Understanding them deepens your grasp of generics and type manipulation
- Lesson 663 — What Are Utility Types?
- Legacy code migration
- Maintaining compatibility with old code patterns
- Lesson 1629 — Prototype Manipulation and Monkey-Patching
- Legacy environments
- might need AMD, UMD, or System formats
- Lesson 1233 — Module Format Configuration with tsc
- Legacy integration boundaries
- When calling ancient APIs or interfacing with systems that predate your type definitions, `unknown` acknowledges reality better than pretending you have guarantees.
- Lesson 1511 — Accept Some Dynamic Behavior with unknown
- Legacy JavaScript modules
- without type definitions
- Lesson 1150 — What declare Does: Ambient Declarations
- Legacy mode
- Continue full transpilation for older environments (current behavior)
- Lesson 1773 — Impact on the TypeScript Compiler
- Legacy projects
- You might need `"moduleResolution": "node"` temporarily
- Lesson 1626 — Module Resolution Confusion
- legitimate scenarios
- where they're the pragmatic choice.
- Lesson 899 — Acceptable Use Cases for SuppressionsLesson 1192 — Non-Null Assertions with strictNullChecks
- Less ceremony
- in smart constructors (the flavor doesn't need explicit assignment)
- Lesson 1357 — Flavoring vs Full Branding
- Less code
- One signature instead of multiple overload declarations
- Lesson 1408 — Union Signatures for Shared Logic
- Less debugging time
- (you find issues in seconds, not hours)
- Lesson 2 — Runtime Errors vs Compile-Time Errors
- Less upfront work
- You only type what the application actively uses
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- Less visual noise
- Your code looks closer to regular JavaScript
- Lesson 155 — The Default Rule: Let TypeScript Infer
- Leverage type inference
- Let TypeScript infer return types and variable types when possible.
- Lesson 1745 — Minimize File-Level Type Dependencies
- Libraries and published packages
- should *never* rely on automated migration for their public API types.
- Lesson 1649 — When Automation Helps vs Manual Migration
- Library boundaries
- and exported functions deserve annotations.
- Lesson 249 — Return Type Annotations Best Practices
- Library code
- where performance affects all consumers
- Lesson 1739 — Use Type Parameters Instead of Lookups
- Library Definition Updates
- Changes to built-in type definitions (like DOM types) can break code that relied on incorrect shapes.
- Lesson 1785 — Community Feedback and Breaking Changes
- Limit recursion depth
- to 3-4 levels maximum
- Lesson 865 — Practical Limits of Path Type ComplexityLesson 1448 — Performance Considerations with Complex infer
- Limit recursion depth manually
- Add a "depth counter" type parameter to stop after a fixed number of levels
- Lesson 1714 — Recursive Type Aliases and Stack Depth
- Limit union size
- Keep string literal unions under ~20-30 members when using intrinsics
- Lesson 839 — Performance and Complexity Considerations
- Limitation
- No type-checking happens during bundling — you must run `tsc --noEmit` separately.
- Lesson 1237 — Bundler Loaders: ts-loader and babel-preset-typescript
- Limitations
- dts-gen can only see what gets executed.
- Lesson 1648 — Alternative Tools: dts-gen and Others
- Limited composition
- Nesting these patterns quickly becomes unreadable and fragile.
- Lesson 1489 — TypeScript's Workaround: Interface Pattern
- Limited type features
- Complex types (the advanced patterns we'll learn later) are awkward or impossible to express
- Lesson 26 — JSDoc Type Annotations in Plain JavaScript
- Limiting template literal complexity
- in key transformations
- Lesson 764 — Performance Considerations with as
- Lines of code
- Across all files
- Lesson 1725 — Using --extendedDiagnostics for Build MetricsLesson 1731 — The --diagnostics Flag for Quick Summaries
- Linters
- like ESLint that understand TypeScript syntax
- Lesson 1796 — Long-Term Vision: TypeScript as a Platform
- List view preview
- Lesson 677 — Pick Use Cases: API Response Subsets
- literal types
- because the value can't change.
- Lesson 158 — Variable Declaration: When to AnnotateLesson 350 — Aliasing Primitive and Literal TypesLesson 405 — The Discriminant Property
- Literal unions
- win when bundle size matters and you don't need runtime features.
- Lesson 481 — Literal Unions vs Enums: Trade-offs
- literal values
- for each variant.
- Lesson 405 — The Discriminant PropertyLesson 406 — Basic Discriminated Union Example
- Literal values stay literal
- `"admin"` stays `"admin"`, not `string`
- Lesson 1417 — const with Object Parameters
- load
- when this code runs?
- Lesson 1117 — Extension Resolution: .ts vs .jsLesson 1728 — Loading Traces in Chrome DevTools
- Local installations
- combined with **version managers**.
- Lesson 47 — Managing Multiple TypeScript Versions
- location
- where the constraint is violated (usually a function call or type instantiation)
- Lesson 630 — Error Messages When Constraints Are ViolatedLesson 1535 — Zod Validators with Hono Middleware
- Long `tsc` build times
- What used to take 2 seconds now takes 30
- Lesson 1477 — Compile-Time Performance Impact
- Long tsc compilation times
- even with `--incremental`
- Lesson 1448 — Performance Considerations with Complex infer
- Look for the never
- When you get cryptic errors assigning values, check if hovering over properties reveals `never` deep in the structure.
- Lesson 448 — Deep Property Conflicts
- Looks for type-specific entries
- keys like `types` or `import` with TypeScript conditions
- Lesson 1116 — The exports Field for Modern Packages
- Lookup approach
- Pass the entire person object and extract `person.
- Lesson 1739 — Use Type Parameters Instead of Lookups
- lookup type
- or **indexed access type**.
- Lesson 640 — Lookup Types: T[K] After keyof ConstraintLesson 651 — Real-World Pattern: Type-Safe Event HandlersLesson 720 — Preserving Property Types
- Lost context
- Developers couldn't understand what data shapes functions expected without reading entire call chains
- Lesson 14 — The Problem TypeScript Set Out to Solve
- Lost relationships
- Giant unions hide the relationships between values.
- Lesson 1651 — The Readability Problem with Giant Union Types
- Low-complexity, repetitive code
- also migrates well with automation.
- Lesson 1649 — When Automation Helps vs Manual Migration
- Low-risk
- DOM queries where element existence is guaranteed
- Lesson 1017 — Measuring Assertion Debt in Your Codebase
M
- Mad Libs contracts
- "This value must be a string that says ___ followed by a dash, then ___.
- Lesson 818 — What Are Template Literal Types?
- Maintain internal consistency
- by controlling all writes
- Lesson 1041 — Getters and Setters with Different Access
- Maintainability
- When the schema changes, regenerate.
- Lesson 1514 — Use Code Generation for Complex PatternsLesson 1629 — Prototype Manipulation and Monkey-Patching
- Maintainable
- Easy to extend with new variants
- Lesson 1512 — Keep Types Simple and ComposableLesson 1688 — The Balance Between Precision and Readability
- MAJOR
- Represents breaking changes (very rare in TypeScript)
- Lesson 1777 — Understanding TypeScript's Release Cadence
- Major Companies
- Lesson 31 — TypeScript Adoption in the Industry
- Major version
- (5): Breaking changes that might require code updates
- Lesson 46 — TypeScript Version Compatibility
- Make it visible
- Post weekly progress updates in team channels
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- Make parameters optional
- if some overloads don't require them
- Lesson 1409 — Implementation Signature Compatibility
- Make strictness opt-in initially
- Begin with `strict: false` and gradually enable flags.
- Lesson 1632 — Team Resistance and Adoption Friction
- Making intentions clear
- Signals to readers that this import won't affect runtime behavior
- Lesson 1109 — Type-Only Import Best Practices
- Manual type duplication
- Copy-paste types between projects (maintenance nightmare)
- Lesson 1551 — What tRPC Solves: The Type-Safety Gap
- Many unions combined
- Consider using plain `string` with runtime validation instead.
- Lesson 828 — Limitations of Template Literals
- mapped type
- is TypeScript's way of creating a new type by transforming each property in an existing type.
- Lesson 717 — What Are Mapped Types?Lesson 853 — Recursive Path Types for Deep Objects
- Mapped type transformations
- Results of mapped type operations
- Lesson 1704 — The Type Cache and Memoization
- Mapped types
- are for transforming a *known set of keys* in a systematic way.
- Lesson 319 — Index Signatures vs Mapped TypesLesson 674 — Deep vs Shallow TransformationsLesson 729 — Mapped Types vs Index SignaturesLesson 840 — Mapping Keys to Template Literal TypesLesson 841 — Dynamic Property Name GenerationLesson 842 — Prefixing and Suffixing Object KeysLesson 843 — The Getters PatternLesson 844 — The Setters Pattern (+4 more)
- Mapped types in constraints
- Lesson 1722 — Generic Constraint Resolution Overhead
- marker type
- that doesn't affect the runtime shape of your object, but tells TypeScript what type `this` should have inside methods.
- Lesson 1084 — Basic ThisType<T> SyntaxLesson 1088 — Limitations of ThisType
- Matched by `include` patterns
- The file must match your glob patterns (e.
- Lesson 1167 — Placement and Scope of Augmentation Files
- Measure impact
- Does your complex type actually prevent bugs, or does it just satisfy perfectionism?
- Lesson 1516 — Prioritize Developer Experience Over Perfect Types
- Medium-risk
- Third-party library types that could change
- Lesson 1017 — Measuring Assertion Debt in Your Codebase
- Memoization
- is the pattern of caching a function's results so repeated calls with the same arguments return cached values instead of recomputing.
- Lesson 598 — Generic Cache and MemoizationLesson 1704 — The Type Cache and Memoization
- Memory usage
- Peak memory consumed
- Lesson 1725 — Using --extendedDiagnostics for Build MetricsLesson 1731 — The --diagnostics Flag for Quick SummariesLesson 1781 — Performance and Scalability FocusLesson 1790 — Performance and Scalability Focus
- Memory usage balloons
- over time during a long coding session
- Lesson 1752 — Restart Language Service When Stuck
- Merge projects
- If they're truly inseparable, combine them into a single project
- Lesson 1228 — Circular References Between Projects
- merges
- all properties and uses the type from the rightmost spread for any duplicates:
- Lesson 331 — Property Override Order and Type MergingLesson 362 — Merging Properties in Interfaces
- Method shorthand
- (`methodName(): ReturnType`) is designed for traditional object methods.
- Lesson 293 — Method Shorthand vs Function PropertiesLesson 343 — Method Signatures in Interfaces
- Method signatures vanish
- Lesson 878 — Lost Autocomplete and IntelliSense
- Method syntax
- is cleaner and matches how you typically write object methods.
- Lesson 292 — Function Properties in Object Types
- Microsoft's Backing
- Lesson 28 — Why TypeScript Won Adoption
- Mid-migration boundaries
- When converting a large codebase from JavaScript, marking areas you'll fix in the next sprint.
- Lesson 896 — When @ts-expect-error Is Preferred
- Middle ground
- (type guards, assertions, specific types) is like trusted traveler programs: balanced security with reasonable convenience.
- Lesson 906 — Type Safety Trade-offs
- Middle layer
- (`V extends T[K]`): ensures the value matches that property's type
- Lesson 660 — Constraint Composition in Higher-Order Functions
- Migration from JavaScript
- Convert files one by one, using `any` for code you haven't typed yet
- Lesson 874 — Gradual Typing Philosophy
- Migration path
- Converting JavaScript to TypeScript incrementally
- Lesson 126 — Introduction to any: The Opt-Out Type
- Migration wiki or doc
- tracking which modules are done
- Lesson 1601 — Team Coordination During Migration
- Minimal compilation
- Flow is primarily a checker, not a full compiler
- Lesson 23 — Flow: Facebook's Type Checker
- MINOR
- New features, improvements, and non-breaking changes
- Lesson 1777 — Understanding TypeScript's Release Cadence
- Minor releases
- (the quarterly updates) bring:
- Lesson 1777 — Understanding TypeScript's Release Cadence
- Minor version
- (3): New features added without breaking existing code
- Lesson 46 — TypeScript Version Compatibility
- Missing `@types/` packages
- Install `@types/library-name`
- Lesson 1123 — Troubleshooting Common Resolution Errors
- Missing `exports` field support
- when using modern packages
- Lesson 1123 — Troubleshooting Common Resolution Errors
- Mixed-type returns
- Functions returning different types based on runtime conditions need union types or overloads
- Lesson 1594 — The .js to .ts Rename Strategy
- Mixing unrelated concerns
- Users, orders, payments, and inventory are distinct domains.
- Lesson 1658 — The Module Boundary Smell
- Modern mode
- Assume runtime handles type erasure (fast)
- Lesson 1773 — Impact on the TypeScript Compiler
- Modern resolution
- Works seamlessly with bundlers and Node.
- Lesson 1116 — The exports Field for Modern Packages
- Modern workflows
- can leverage **Deno or Bun**, which run TypeScript natively without configuration.
- Lesson 75 — Choosing the Right Execution Method for Your Use Case
- Modification is terrifying
- changing one character breaks everything in mysterious ways
- Lesson 1504 — Unmaintainable Type Gymnastics
- module
- requiring explicit imports.
- Lesson 1158 — The global Scope in .d.ts FilesLesson 1159 — export {} to Force Module Context
- module augmentation
- combined with **declaration merging**—you can "reopen" a module and add new properties to its exported interfaces without modifying the original source.
- Lesson 1165 — Adding Properties to Existing InterfacesLesson 1179 — Avoiding Global Pollution
- Module mode
- Declarations must be explicitly imported to be used, just like regular TypeScript files.
- Lesson 1158 — The global Scope in .d.ts Files
- Module system
- to use
- Lesson 49 — What is tsconfig.jsonLesson 1112 — The moduleResolution Compiler Option
- Module system preservation
- Your `import`/`export` statements remain as-is
- Lesson 1232 — tsc Output: Per-File Transpilation
- Module-scoped augmentations
- When using `declare module 'some-package'` to add types to a third-party library, add `export {}` to keep those augmentations modular.
- Lesson 1159 — export {} to Force Module Context
- modules
- you can reopen a module namespace and add or extend types, even for code you imported from elsewhere.
- Lesson 364 — Declaration Merging with ModulesLesson 1169 — Common Pitfalls in Module Augmentation
- Monorepos
- Check types across packages without generating duplicate outputs
- Lesson 74 — Running Type Checks Without Emitting FilesLesson 1610 — Declaration Files for JavaScript LibrariesLesson 1746 — Use Incremental Compilation and Build Modes
- More than 2-3 unions
- Probably too many combinations to be useful.
- Lesson 828 — Limitations of Template Literals
- Most TypeScript code involves
- Lesson 1491 — Why Most Developers Don't Need HKTs
- Multi-boolean collapse
- Three booleans (`isPending`, `isSaved`, `isFailed`) become one discriminated union with three cases.
- Lesson 1346 — Refactoring Toward Impossible States
- Multi-format support
- Different files for ESM vs CommonJS without confusion
- Lesson 1116 — The exports Field for Modern Packages
- Multiple Assertions in Sequence
- Lesson 1016 — Code Review Red Flags with Assertions
- Multiple brands
- let you stack these constraints using intersection types.
- Lesson 1354 — Multiple Brands on One Type
- Multiple Client Languages
- Mobile apps in Swift or Kotlin, Python scripts, or third-party integrations can't use tRPC procedures.
- Lesson 1559 — Trade-offs: When tRPC Fits vs Doesn't
- Multiple contracts
- that don't fit in a linear inheritance chain
- Lesson 1055 — Combining implements and extends
- Multiple focused functions
- beat one "does everything" generic.
- Lesson 662 — When Constraint Composition Becomes Overengineering
- Multiple functions
- Split one complex generic into focused helpers
- Lesson 652 — When Conditional Constraints Become Too Complex
- Multiple inference sites
- Every `infer` in a complex conditional adds constraint-solving overhead
- Lesson 1472 — Limits of Type-Level Computation
- Multiple teams need contracts
- Front-end and back-end teams can work in parallel once interfaces are agreed upon
- Lesson 1326 — Type-First vs Code-First Trade-offs
- multiple type parameters
- come in.
- Lesson 530 — Multiple Type ParametersLesson 600 — Explicit Type Arguments with Angle BracketsLesson 787 — Multiple Type Parameters and DistributionLesson 823 — Multi-Part Template Patterns
- Multiple valid choices exist
- No single default makes sense for all use cases
- Lesson 570 — When to Use Defaults vs Required Parameters
- Multiple variadic parameters
- Functions with three or more rest tuple parameters
- Lesson 1718 — Variadic Tuple Complexity
- Must
- have a `string` as the first element
- Lesson 121 — Rest Elements in TuplesLesson 233 — Assertion Functions vs Type PredicatesLesson 302 — Optional vs undefined UnionLesson 427 — Exhaustive Matching with Return TypesLesson 462 — Literal Types in Return ValuesLesson 627 — Constraining One Type Parameter to AnotherLesson 729 — Mapped Types vs Index SignaturesLesson 897 — @ts-nocheck for Entire Files (+7 more)
- MutableRefObject
- For mutable value containers (writable `.
- Lesson 1521 — Typing useRef for DOM Elements and Mutable Values
- mutations
- are procedures that modify server state—creating, updating, or deleting data.
- Lesson 1544 — Mutation Procedures with Input TypesLesson 1561 — What Distinguishes Queries from Mutations
N
- naked type parameter
- a bare `T` without any wrappers.
- Lesson 770 — Non-Distributive ConditionalsLesson 779 — What Makes a Conditional Type Distributive
- name
- that object structure so you can reuse it and refer to it clearly.
- Lesson 338 — What Interfaces AreLesson 497 — Enum Member Name vs Value
- Name your constraint types
- instead of using inline conditional types
- Lesson 650 — Error Messages from Failed Conditional Constraints
- Namespaces
- provide a way to group these type definitions under a single top-level name, preventing pollution of the global scope while maintaining compatibility with how the library actually works.
- Lesson 1134 — Namespaces in Declaration FilesLesson 1143 — Namespaces in DeclarationsLesson 1257 — Namespace Exports and LimitationsLesson 1769 — Syntax That Would Be Standardized
- narrow
- union types.
- Lesson 191 — Using typeof to Guard PrimitivesLesson 388 — Union Types in Function ParametersLesson 799 — Constraints on infer VariablesLesson 1665 — Unions Widen, Generics Narrow
- narrows
- the type of `value` from `unknown` to `string` inside that block.
- Lesson 132 — Narrowing unknown with typeofLesson 199 — Truthiness Narrowing Basics
- Native `tsconfig.json` support
- Respects your existing TypeScript configuration
- Lesson 71 — Running TypeScript in Bun
- Natural boundaries
- Application layers often align with migration phases
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- Need careful error handling
- (failed mutations may need rollback)
- Lesson 1561 — What Distinguishes Queries from Mutations
- Need documentation
- Object types or interfaces are self-documenting.
- Lesson 828 — Limitations of Template Literals
- Nested loops
- that invoke generic validation or mapping functions
- Lesson 1724 — Excessive Type Instantiation in Loops
- Nested mapped types
- Each layer multiplies the work the checker must do
- Lesson 1472 — Limits of Type-Level Computation
- Nested routers
- let you organize procedures into hierarchical namespaces, and TypeScript preserves full type safety through every level.
- Lesson 1547 — Nested Routers and Namespace Types
- Network responses
- Data from `fetch()` calls absolutely requires runtime validation.
- Lesson 1282 — When Type Assertions Are Acceptable
- Nightly builds
- (`npm install typescript@next`) contain the absolute latest changes—features that might ship in the next release or might be experimental proofs-of-concept.
- Lesson 1780 — Features in Active Development
- No
- Keep the primitive type as-is
- Lesson 813 — The DeepReadonly PatternLesson 893 — Performance and Runtime ImpactLesson 1282 — When Type Assertions Are Acceptable
- No accidental internal leaks
- implementation details aren't exposed
- Lesson 1251 — Verifying Library Type Exports
- No associated data
- You can't attach error messages, progress percentages, or timestamps to specific states
- Lesson 1653 — Discriminated Unions vs Flat String Unions
- No configuration required
- Works with any TypeScript file immediately
- Lesson 71 — Running TypeScript in Bun
- No enforcement
- It's still JavaScript—the code runs even with type errors
- Lesson 26 — JSDoc Type Annotations in Plain JavaScript
- no idea
- what shape that data actually has at runtime.
- Lesson 926 — Basic Runtime Type Guard for API DataLesson 1627 — JSON and Dynamic Data Structures
- No implicit unsafety
- Operations that TypeScript allows (with warnings) might be completely blocked in Hegel.
- Lesson 27 — Hegel: A Stronger Type System for JavaScript
- No information is lost
- Unlike using `any`, the type is preserved exactly
- Lesson 609 — The Identity Function Pattern
- No installation needed
- No `ts-node`, no `tsx`, no extra packages
- Lesson 71 — Running TypeScript in Bun
- No modifier at all
- *preserves* whatever the original property had
- Lesson 752 — Common Pitfalls with Modifier Syntax
- No mutations
- once created, data never changes
- Lesson 25 — PureScript and Elm: Pure Functional Alternatives
- No null or undefined
- these don't exist in the language
- Lesson 25 — PureScript and Elm: Pure Functional Alternatives
- No real abstraction
- You're manually encoding what the type system should handle natively.
- Lesson 1489 — TypeScript's Workaround: Interface Pattern
- No runtime errors
- if it compiles, entire categories of bugs are impossible
- Lesson 25 — PureScript and Elm: Pure Functional Alternatives
- No runtime lookups
- JavaScript doesn't need to find a property on an object.
- Lesson 502 — Performance Benefits of const enums
- No safety net
- Typos, incorrect function calls, and property access errors only appeared when users triggered specific code paths
- Lesson 14 — The Problem TypeScript Set Out to Solve
- No side effects
- every function must return predictable results
- Lesson 25 — PureScript and Elm: Pure Functional Alternatives
- No structure
- Everything is one flat list with no semantic grouping
- Lesson 1653 — Discriminated Unions vs Flat String Unions
- No type inference
- TypeScript can't infer the HKT interface from actual generic types automatically.
- Lesson 1489 — TypeScript's Workaround: Interface Pattern
- Node.js (older versions)
- expects CommonJS (`require` and `module.
- Lesson 1233 — Module Format Configuration with tsc
- Node.js environment (`NodeJS.Global`)
- Lesson 1174 — Augmenting Built-in Global Interfaces
- Nominally
- distinct (TypeScript treats it as incompatible with plain strings)
- Lesson 1362 — Simulating Opaque Types with Branding
- Non-breaking at call sites
- Functions accepting `unknown` still accept any argument, just like `any` did
- Lesson 1676 — Replacing any with unknown for Safe Migration
- Non-critical code paths
- Logging, UI hints, or optional enhancements where missing a case isn't catastrophic
- Lesson 426 — When Exhaustiveness Isn't Needed
- Non-homomorphic mapped types
- Lesson 1720 — Homomorphic vs Non-Homomorphic Mapped Types
- Non-intrusive
- Doesn't affect how JavaScript actually executes
- Lesson 1769 — Syntax That Would Be Standardized
- Non-TypeScript Consumers
- Even JavaScript-only projects miss out on tRPC's benefits.
- Lesson 1559 — Trade-offs: When tRPC Fits vs Doesn't
- not
- `null` or **not** `undefined`.
- Lesson 204 — Narrowing with !== and !==Lesson 691 — Exclude vs Extract Mental ModelLesson 756 — Filtering Keys with neverLesson 1082 — What is ThisType<T>Lesson 1578 — React Query Integration and Inferred HooksLesson 1679 — Localized any with Strict Boundaries
- Not cached
- by default (you want fresh data after changes)
- Lesson 1561 — What Distinguishes Queries from Mutations
- Not in `node_modules`
- Your augmentations live in *your* code, not in the library's folder
- Lesson 1167 — Placement and Scope of Augmentation Files
- Null safety
- (`strictNullChecks`) prevents null/undefined errors but doesn't help with implicit `any` types.
- Lesson 1220 — Combining Safety Flags for Maximum Protection
- Nullable
- The property exists but its value is `null`: `{ name: "Alice", age: null }`
- Lesson 1289 — Optional and Nullable Fields
- number index signature
- (`[key: number]: Type`) is designed for array-like structures where you access values by numeric index, like `items[0]` or `scores[42]`.
- Lesson 312 — String vs Number Index SignaturesLesson 636 — keyof with Index Signatures
- Nx
- , and **pnpm workspaces** all take advantage of TypeScript's project reference system:
- Lesson 38 — Monorepo Tooling and TypeScript
O
- Object property existence checks
- Lesson 1190 — The Cost of strict: False Positives
- object shapes
- .
- Lesson 374 — Primitive and Literal Types: Only Type Aliases WorkLesson 1744 — Prefer interface Over type for Object Shapes
- Object transformations
- (Partial, Required, Readonly, Pick, Omit, Record)
- Lesson 716 — The Full Standard Library Reference
- object type literals
- .
- Lesson 288 — What Are Object Type LiteralsLesson 340 — Interface vs Object Type Literal
- OCaml
- , a strongly-typed functional programming language known for having one of the most powerful type systems in existence.
- Lesson 24 — ReasonML and ReScript: OCaml-Based AlternativesLesson 1488 — Languages That Have HKTs
- Onboarding friction
- New team members had no way to discover how existing code worked without extensive documentation or asking colleagues
- Lesson 14 — The Problem TypeScript Set Out to Solve
- Onboarding takes longer
- New developers can't easily understand what data flows through your functions without reading implementation details or documentation (which is often outdated).
- Lesson 3 — The Cost of Dynamic Typing at Scale
- Onboarding time explodes
- New team members spend days understanding your type utilities instead of building features.
- Lesson 1475 — The Readability Cost of Complex Type-Level Code
- once
- and let TypeScript adapt it to any type:
- Lesson 535 — The Relationship Between Generics and ReusabilityLesson 579 — API Response WrappersLesson 1487 — The Generic Problem HKTs Solve
- one
- repository type that adapts to any entity shape.
- Lesson 614 — Generic Repository PatternLesson 1500 — Practical Example: Generic map Over Container Types
- One ecosystem, not two
- The split between "JavaScript files" and "TypeScript files" would blur
- Lesson 1786 — Long-Term Vision: Types in JavaScript
- only
- removes `null` and `undefined`.
- Lesson 199 — Truthiness Narrowing BasicsLesson 203 — Loose Equality == null PatternLesson 205 — Comparing Against Literal ValuesLesson 322 — What Are Excess Property ChecksLesson 691 — Exclude vs Extract Mental ModelLesson 1097 — Why type-only imports matter for bundlersLesson 1125 — When You Need Declaration FilesLesson 1245 — What emitDeclarationOnly Does (+4 more)
- Only export
- the branded type and the smart constructor function
- Lesson 1352 — Smart Constructor Pattern
- Opaque Type Pattern
- takes branding to its ultimate conclusion: instead of just marking a type with a brand, you hide the entire type definition inside a module and only export functions that create and work with it.
- Lesson 1355 — Opaque Type Pattern
- Open-Source Ecosystem
- Lesson 31 — TypeScript Adoption in the Industry
- OpenAPI → TypeScript
- Tools read REST API specs and generate request/response types
- Lesson 1514 — Use Code Generation for Complex Patterns
- OpenAPI/REST with Code Generation
- involves tools that generate TypeScript clients from OpenAPI specifications.
- Lesson 1581 — The End-to-End Type Safety Landscape
- OpenAPI/Swagger
- You define APIs in YAML/JSON, then generate client code with tools like `openapi-generator`
- Lesson 1555 — No Code Generation Required
- OpenAPI/Swagger code generation
- Generate types from API specs (extra build step, spec must stay synchronized)
- Lesson 1551 — What tRPC Solves: The Type-Safety Gap
- Opt-In Strictness
- Most strictness improvements ship as opt-in flags rather than defaults, giving teams control over when they adopt them.
- Lesson 1785 — Community Feedback and Breaking Changes
- Optimize builds
- Help bundlers eliminate unused type code
- Lesson 1106 — export type for Type-Only Exports
- Optimizing configuration
- See if TypeScript is checking unnecessary paths
- Lesson 1120 — Module Resolution Tracing with --traceResolution
- optional
- using the `?
- Lesson 120 — Optional Tuple ElementsLesson 250 — Optional Parameters with ?Lesson 672 — Combining Utility TypesLesson 1205 — exactOptionalPropertyTypes: Optional vs UndefinedLesson 1289 — Optional and Nullable FieldsLesson 1775 — Challenges and Controversies
- Optional `?`
- Property type is `string | undefined` — it's *meant* to sometimes be undefined
- Lesson 1022 — Optional Properties in ClassesLesson 1357 — Flavoring vs Full Branding
- Optional additions
- Consider also enabling `noUncheckedIndexedAccess` and `exactOptionalPropertyTypes` for even more safety, though these aren't included in the `strict` flag.
- Lesson 1208 — Combining Strictness Options for Maximum Safety
- Optional dependency chains
- If `connectionId` requires `sessionToken`, don't make both optional—create separate `Connected` and `Disconnected` types.
- Lesson 1346 — Refactoring Toward Impossible States
- Optional properties
- (`prop?
- Lesson 315 — Optional Properties vs Index SignaturesLesson 442 — Intersection vs Union for Optional PropertiesLesson 1205 — exactOptionalPropertyTypes: Optional vs UndefinedLesson 1346 — Refactoring Toward Impossible States
- Order-dependent resolution
- Lesson 1628 — Function Overload Conflicts
- Others
- include Parcel (zero-config approach), Vite (uses esbuild under the hood for dev speed), and swc (Rust-based, similar philosophy to esbuild).
- Lesson 1234 — Bundlers: Webpack, Rollup, esbuild, and Others
- Outer layer
- (`K extends keyof T`): ensures you pick a valid property
- Lesson 660 — Constraint Composition in Higher-Order Functions
- Output directories
- `dist`, `build`, `out`—these contain compiled JavaScript, not source code you're editing.
- Lesson 1751 — excludeFiles and IDE Performance
- Overlapping parameter types
- Lesson 1628 — Function Overload Conflicts
- overload signatures
- (just the types, no body), followed by one **implementation signature** with the actual code:
- Lesson 268 — What Are Function Overloads?Lesson 269 — Overload Syntax: Signatures vs ImplementationLesson 272 — The Implementation Signature Must Be CompatibleLesson 1404 — What Function Overloads Are
- Overloaded functions
- , **non-function types**, and **`never` types** expose situations where these utilities either produce surprising results or fail to capture the full picture you might expect.
- Lesson 708 — Limitations and Edge Cases
- Overloads
- are more precise—they let you express relationships between specific input types and their corresponding output types.
- Lesson 278 — Overloads vs Union ParametersLesson 550 — Generic Functions vs Function OverloadsLesson 1668 — Overloads vs Generic Union Parameters
- Overloads excel when
- Lesson 1413 — Guidelines for Choosing Between Them
P
- Package resolution issues
- Which `package.
- Lesson 1120 — Module Resolution Tracing with --traceResolution
- Parallel arrays
- where indices must align (`names: string[]` and `ages: number[]`)
- Lesson 1346 — Refactoring Toward Impossible States
- Parallel builds
- Independent projects can compile simultaneously
- Lesson 1229 — Monorepo Patterns with References
- Parallel compilation
- (independent projects build simultaneously)
- Lesson 1221 — What Are Composite Projects?
- Parallel processing
- Different files can be parsed simultaneously
- Lesson 1699 — TypeScript's Two-Phase Compilation Model
- Parameter annotation
- `name: string` tells TypeScript this function accepts a string argument.
- Lesson 236 — Function Type Syntax
- Parameter approach
- Pass the age directly as a separate parameter
- Lesson 1739 — Use Type Parameters Instead of Lookups
- parameter properties
- a way to declare properties directly in the constructor by adding an access modifier (`public`, `private`, `protected`) or `readonly` to the parameter:
- Lesson 1024 — Parameter Properties ShorthandLesson 1032 — public: The Default VisibilityLesson 1769 — Syntax That Would Be Standardized
- Parameter typed as `never`
- This means TypeScript expects no valid value can ever be passed.
- Lesson 956 — Creating an assertNever Helper
- parameter types
- in the function signature.
- Lesson 601 — Inference from Function ArgumentsLesson 617 — Generic Memoization and Caching
- Parameters need context
- beyond their type (valid ranges, special values, format expectations)
- Lesson 1684 — JSDoc Comments for Public APIs
- Parcel
- has built-in TypeScript support with zero configuration
- Lesson 72 — Using TypeScript with Bundlers (Webpack, Vite, Parcel)Lesson 73 — TypeScript in the Browser via Build Tools
- parse
- it.
- Lesson 932 — Integrating Zod for unknown ValidationLesson 1712 — The Cost of Deep Conditional TypesLesson 1770 — What Gets Ignored vs What Gets Parsed
- Parse the error output
- (TypeScript outputs errors in a structured format)
- Lesson 1270 — Reporting Type Errors in Pull Requests
- Parsing and Binding Phase
- TypeScript reads your source files, builds an Abstract Syntax Tree (AST), and establishes what symbols (variables, functions, types) exist and where they're declared.
- Lesson 1699 — TypeScript's Two-Phase Compilation Model
- Partial Handling Is Acceptable
- Lesson 963 — When to Skip Exhaustiveness Checks
- Partial matching by design
- You're intentionally filtering or processing only specific union members
- Lesson 426 — When Exhaustiveness Isn't Needed
- Pattern 2: Runtime string
- Lesson 1623 — Dynamic Property Access Patterns
- Pattern match
- against `Promise<infer U>` — if `T` is a Promise, capture what it wraps in `U`
- Lesson 1447 — Building Awaited with infer
- Pattern matching
- A powerful way to handle different data shapes
- Lesson 24 — ReasonML and ReScript: OCaml-Based AlternativesLesson 1434 — What infer Actually Does
- Performance matters
- You want zero runtime overhead and the smallest possible bundle size
- Lesson 506 — When to Use const enums
- Performance optimizations
- Engine-level improvements for BigInt operations
- Lesson 1764 — Numeric Separators and BigInt Evolution
- Performance-critical paths
- Sometimes complex conditional types slow down the compiler significantly.
- Lesson 1511 — Accept Some Dynamic Behavior with unknown
- Performs an initial build
- of your project and all its references
- Lesson 1230 — Watch Mode with Project References
- phantom type
- ) lets you mark certain arrays as guaranteed non-empty:
- Lesson 1345 — Empty Array Edge CasesLesson 1356 — Phantom Types for StateLesson 1428 — The Phantom Type Builder Pattern
- Phase 1
- Start with `noImplicitAny` — it catches the most egregious gaps without changing runtime behavior assumptions.
- Lesson 1208 — Combining Strictness Options for Maximum SafetyLesson 1597 — The Strictness Dial ApproachLesson 1615 — Setting Up for Incremental Migration
- Phase 1: Bulk Conversion
- Lesson 1650 — Combining Tools with Incremental Strategy
- Phase 2
- Add `strictNullChecks` — this is the biggest leap but catches the most bugs.
- Lesson 1208 — Combining Strictness Options for Maximum SafetyLesson 1597 — The Strictness Dial ApproachLesson 1615 — Setting Up for Incremental Migration
- Phase 2: Incremental Refinement
- Lesson 1650 — Combining Tools with Incremental Strategy
- Phase 3
- Enable remaining flags one at a time, fixing errors as you go.
- Lesson 1208 — Combining Strictness Options for Maximum SafetyLesson 1597 — The Strictness Dial ApproachLesson 1615 — Setting Up for Incremental Migration
- Phase 3: Progressive Strictness
- Lesson 1650 — Combining Tools with Incremental Strategy
- Phase 4
- Enable remaining strict flags one by one: `strictFunctionTypes`, `strictBindCallApply`, `strictPropertyInitialization`.
- Lesson 1597 — The Strictness Dial Approach
- Phase 5
- Finally, replace individual flags with the single `strict: true` setting.
- Lesson 1597 — The Strictness Dial Approach
- PlainTime
- Just a wall-clock time (hour, minute, second)
- Lesson 1761 — Temporal API and Date Type Safety
- Platform-Native Annotations
- Lesson 1270 — Reporting Type Errors in Pull Requests
- Playwright
- all support TypeScript out of the box or with minimal configuration.
- Lesson 37 — Testing with TypeScript
- Plugin registration systems
- , **CSS imports**, **global type augmentations** all need regular imports to execute.
- Lesson 1107 — Type-Only Imports with Side Effects
- Polyfills
- that add new methods to built-in prototypes
- Lesson 1172 — What Global Augmentation MeansLesson 1629 — Prototype Manipulation and Monkey- Patching
- polymorphic
- it adapts based on the actual instance type.
- Lesson 1066 — Using this as a Return TypeLesson 1068 — this in Base Class MethodsLesson 1075 — Typing Methods That Return this
- Polymorphic plugin systems
- When third-party code registers handlers or transforms, you often can't know their shapes in advance.
- Lesson 1511 — Accept Some Dynamic Behavior with unknown
- Poor discoverability
- Finding "what events relate to orders" requires scanning the entire union rather than looking at an `OrderEvents` module.
- Lesson 1658 — The Module Boundary Smell
- Poor documentation
- The type itself provides little insight into *what* these values mean or *when* they're used.
- Lesson 1651 — The Readability Problem with Giant Union Types
- Post comments
- on specific file lines via the platform's API (GitHub, GitLab, etc.
- Lesson 1270 — Reporting Type Errors in Pull Requests
- Practical soundness
- It accepts some technically "unsafe" patterns if they're common in JavaScript
- Lesson 23 — Flow: Facebook's Type Checker
- Practical synergy
- When you use optional chaining (`obj?
- Lesson 693 — NonNullable in Strictness Contexts
- Pragmatic deadlines
- Ship features now, improve type coverage later
- Lesson 874 — Gradual Typing Philosophy
- Pre-commit hooks
- Catch type errors before code reaches your repository
- Lesson 74 — Running Type Checks Without Emitting FilesLesson 1601 — Team Coordination During Migration
- precision
- (the exact literal type is preserved).
- Lesson 628 — Constraints with Union TypesLesson 629 — Constraints and Type InferenceLesson 1420 — Combining const with Constraints
- Precompute when possible
- Define explicit types instead of computing transformations
- Lesson 839 — Performance and Complexity Considerations
- Predictable dependencies
- Utilities typically have fewer dependencies themselves
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- Prefer named exports
- for most TypeScript projects:
- Lesson 1092 — Named exports vs default exports for types
- preserve type information
- at every level of nesting while maintaining flexibility through generics.
- Lesson 655 — Recursive Constraints for Tree StructuresLesson 1250 — Combining with Composite Projects
- preserves
- whatever type you specify.
- Lesson 579 — API Response WrappersLesson 1664 — The Identity Function Test
- Preserves literal types
- `"development"` stays `"development"`, not `string`
- Lesson 471 — as const on Objects
- Preserving
- means distributing your mapping operation across each union member individually, maintaining the union shape in the output.
- Lesson 738 — Preserving vs Transforming Union Members
- Prevent confusion
- Avoid ambiguity between type and value exports
- Lesson 1106 — export type for Type-Only Exports
- Preventing basic mistakes
- (wrong property names, mismatched function arguments)
- Lesson 1509 — Embrace Runtime Checks Over Type Gymnastics
- Prevents accidental runtime usage
- If you try to use a type-only import as a value, TypeScript will immediately error.
- Lesson 1095 — Type-only import syntax with import type
- Private + readonly
- = Internal immutable data that even the class itself shouldn't modify after initialization:
- Lesson 1040 — Combining readonly with Access Modifiers
- Private Constructors Pattern
- uses TypeScript's `private` access modifier on a class constructor to make it impossible to call `new MyClass()` from outside the class.
- Lesson 1364 — Private Constructors Pattern
- Production builds
- require `tsc` to compile your TypeScript into JavaScript.
- Lesson 75 — Choosing the Right Execution Method for Your Use Case
- project references
- specifically to solve this problem, and modern monorepo tools build on top of this feature.
- Lesson 38 — Monorepo Tooling and TypeScriptLesson 76 — Understanding Compilation Modes: Build vs Watch vs ProjectLesson 1122 — Resolution for MonoreposLesson 1221 — What Are Composite Projects?Lesson 1229 — Monorepo Patterns with ReferencesLesson 1699 — TypeScript's Two-Phase Compilation ModelLesson 1753 — Workspace Recommendations for Speed
- Project-Local Declaration Files
- Lesson 1130 — Typing Third-Party Libraries
- Promise unwrapping on non-promises
- Lesson 1446 — Common Pitfalls: When infer Fails to Match
- Promise wrappers
- must preserve the resolved value type
- Lesson 1663 — When Generics Are Better: Type Preservation Needed
- Promoted to `strict`
- In a later major version, it becomes part of the `strict` family
- Lesson 1194 — Future Additions to strict
- Proper module structure
- exports match your runtime exports
- Lesson 1251 — Verifying Library Type Exports
- Properties
- Instance variables with their types (including `readonly` if applicable)
- Lesson 1141 — Declaring Classes
- Properties become `readonly`
- TypeScript infers them as immutable
- Lesson 1417 — const with Object Parameters
- Property access
- When you access a property on a union, TypeScript computes which members have that property.
- Lesson 1708 — Union and Intersection Expansion
- Property keys
- Symbols can be object property names without name collisions
- Lesson 90 — The symbol Type
- Property suggestions disappear
- Lesson 878 — Lost Autocomplete and IntelliSense
- Property syntax
- is useful when you need to emphasize that a function is just a value being stored, or when dealing with optional function properties.
- Lesson 292 — Function Properties in Object Types
- PropsType
- defines the component's props.
- Lesson 1527 — Typing forwardRef for Ref-Forwarding Components
- Protected + readonly
- = Data accessible to subclasses but frozen for everyone:
- Lesson 1040 — Combining readonly with Access Modifiers
- Protection within your domain
- (catching `userId`/`productId` swaps)
- Lesson 1357 — Flavoring vs Full Branding
- Protocol Buffers → TypeScript
- Generate types from `.
- Lesson 1514 — Use Code Generation for Complex Patterns
- Prototype manipulation
- Heavy use of `this` binding or prototypal inheritance needs careful typing
- Lesson 1594 — The .js to .ts Rename Strategy
- Prototype or Throwaway Code
- Lesson 963 — When to Skip Exhaustiveness Checks
- Provide autocomplete
- for procedure names and parameters
- Lesson 1569 — How tRPC Propagates Types Across the Network Boundary
- Provide concrete types
- lock the class to specific types like `string` or `number`
- Lesson 556 — Implementing Generic Interfaces
- Provide escape hatches
- allow `string` as a fallback type
- Lesson 865 — Practical Limits of Path Type Complexity
- Provide type arguments when
- Lesson 608 — Best Practices for Inference vs Explicit Types
- Provide TypeScript types
- automatically through inference
- Lesson 1302 — io-ts and Codec-Based Inference
- Public + readonly
- = Externally visible but immutable:
- Lesson 1040 — Combining readonly with Access Modifiers
- public API
- a promise to other parts of your codebase (or other developers) about what your function accepts and returns.
- Lesson 160 — Inference Across Module BoundariesLesson 279 — Real-World Overload Examples
- Public API boundaries first
- exported functions and classes
- Lesson 1621 — Dealing with Implicit any in Legacy Code
- Public API Development
- When building libraries or APIs that others will consume, type-first design catches contract issues before they reach users.
- Lesson 1333 — When Type-First Design Pays Off
- Public API functions
- should always have return type annotations.
- Lesson 249 — Return Type Annotations Best Practices
- public APIs
- (what consumers see), inferred types for **internal validation** (what actually gets checked).
- Lesson 1309 — When to Explicitly Annotate vs Purely InferLesson 1559 — Trade-offs: When tRPC Fits vs Doesn't
- Public APIs are self-documenting
- function signatures with annotated parameters and return types clearly communicate intent without reviewers needing to trace through implementation
- Lesson 166 — Balancing Inference and Explicitness in Teams
- Public REST APIs
- requiring OpenAPI documentation (ts-rest/zodios)
- Lesson 1590 — Hybrid Strategies: Mixing Approaches
- Pure inference
- means your schema is the single source of truth.
- Lesson 1309 — When to Explicitly Annotate vs Purely Infer
Q
- queries
- are procedures that fetch data without changing server state, while **mutations** are procedures that modify server state.
- Lesson 1561 — What Distinguishes Queries from MutationsLesson 1562 — tRPC query() Method Basics
- Quick prototypes
- When you're experimenting to see if an idea works, type definitions slow you down.
- Lesson 12 — When Static Typing Isn't Worth It
- Quick prototyping
- Testing ideas without compilation delays
- Lesson 67 — tsx: A Faster Alternative to ts-node
R
- read
- values and use non-mutating methods like `map`, `filter`, and `slice`—these return new arrays without changing the original.
- Lesson 306 — Readonly Arrays and TuplesLesson 1562 — tRPC query() Method Basics
- readability
- , and **maintenance**.
- Lesson 294 — Anonymous vs Named Object TypesLesson 447 — Intersection Order IndependenceLesson 663 — What Are Utility Types?Lesson 1104 — Mixed Imports: Types and ValuesLesson 1652 — Breaking Down Large Unions into Semantic GroupsLesson 1759 — Pipeline Operator and Type Flow
- Readability matters
- Code like `Partial<User>` immediately communicates intent.
- Lesson 715 — When to Use vs Custom Mapped TypesLesson 1481 — Simple Types with Good Tests
- Readable
- Anyone can understand `User | Admin` or `Loggable & Serializable`
- Lesson 1512 — Keep Types Simple and Composable
- readonly array
- is an array type that TypeScript treats as *immutable*.
- Lesson 108 — Readonly ArraysLesson 671 — Readonly with Arrays and Tuples
- readonly tuple
- with exact literal element types:
- Lesson 470 — as const on ArraysLesson 1523 — Typing Custom Hooks with Return Tuples
- readonly tuples
- Lesson 1372 — Tuple Type Inference from LiteralsLesson 1416 — const vs Normal Type Parameters
- Real example
- Lesson 1441 — Rest Elements with infer
- ReasonML
- (now evolved into **ReScript**) compiles to JavaScript, just like TypeScript.
- Lesson 24 — ReasonML and ReScript: OCaml-Based Alternatives
- Reassigning the whole tuple
- (you still can't if it's declared with `const`)
- Lesson 122 — Readonly Tuples
- Record utility
- says "this object has exactly these known keys, all with the same value type":
- Lesson 685 — Record vs Index Signatures
- Recurse
- by calling `MyAwaited<U>` — handles nested promises
- Lesson 1447 — Building Awaited with inferLesson 1467 — Type-Level Accumulators
- Recurse on property types
- `DeepReadonly<T[K]>` handles nesting
- Lesson 802 — Building a Deep Readonly with infer
- recursion
- to unwrap nested structures layer by layer until reaching the core type, enabling type-safe operations on arbitrarily nested data.
- Lesson 816 — The Flatten Pattern for Nested TypesLesson 1383 — Flattening Nested TuplesLesson 1468 — Type-Level Iteration Over TuplesLesson 1471 — Type-Level String Manipulation
- recursive conditional types
- with `infer`.
- Lesson 1382 — Reversing Tuple TypesLesson 1711 — Understanding Type Instantiation Depth
- Recursive mapped types
- that traverse object structures multiple levels deep can exponentially increase resolution time.
- Lesson 1749 — Complex Types and Autocomplete Lag
- Recursive mapping
- If yes, map over all keys with `[K in keyof T]`, make each optional (`?
- Lesson 812 — The DeepPartial Pattern
- Recursive tuple operations
- Types that reference themselves with accumulating spreads
- Lesson 1718 — Variadic Tuple Complexity
- Recursive type aliases
- are extremely limited or unsupported in JSDoc.
- Lesson 1640 — JSDoc Limitations vs Native TypeScript
- Recursive type definitions
- that expand many levels deep
- Lesson 1749 — Complex Types and Autocomplete Lag
- Recursive type operations
- that call generic utilities repeatedly
- Lesson 1724 — Excessive Type Instantiation in Loops
- recursively
- applies the same treatment all the way down the tree.
- Lesson 472 — Nested as const InferenceLesson 816 — The Flatten Pattern for Nested TypesLesson 853 — Recursive Path Types for Deep Objects
- Recursively generate sub-paths
- for nested objects
- Lesson 852 — Constructing Path Unions from Object Keys
- Recursively instantiate types
- at every level
- Lesson 1448 — Performance Considerations with Complex infer
- Red squiggles
- appear under type errors in JSDoc-annotated code
- Lesson 1642 — Validating JSDoc Coverage with Tooling
- Red squiggles disappear
- even though errors clearly exist
- Lesson 1752 — Restart Language Service When Stuck
- Reduced bundle size
- No enum object means fewer bytes shipped to users.
- Lesson 502 — Performance Benefits of const enums
- Reduced context switching
- Error location, message, and code are all in one view
- Lesson 1270 — Reporting Type Errors in Pull Requests
- Reduced tooling burden
- Fewer moving parts means fewer things to break, configure, or understand.
- Lesson 1768 — The Motivation: Types Without Transpilation
- refactoring
- to break the cycle.
- Lesson 1228 — Circular References Between ProjectsLesson 1652 — Breaking Down Large Unions into Semantic Groups
- Refactoring Becomes Dangerous
- Lesson 898 — The Danger of Suppression Comments
- Refactoring becomes terrifying
- Want to rename a property or change what a function returns?
- Lesson 3 — The Cost of Dynamic Typing at ScaleLesson 1475 — The Readability Cost of Complex Type- Level Code
- Refactoring confidence
- When you change a type definition, CI immediately tells you everywhere that breaks across the entire project.
- Lesson 1263 — Why Type-Check in CI
- Refactoring Large Systems
- Before restructuring existing code, designing target types first creates a clear roadmap.
- Lesson 1333 — When Type-First Design Pays Off
- Refactoring overhead
- changing brands propagates through codebases
- Lesson 1359 — Tradeoffs and Ergonomics
- Refactoring safety
- Rename a value, and TypeScript finds every usage across your codebase.
- Lesson 520 — Refactoring Safety and Autocomplete
- References internal type positions
- meaningless to the developer
- Lesson 1476 — Debugging Complex Type Errors
- Refine further
- based on specific characteristics (via conditional)
- Lesson 773 — Conditional Types with Generic Constraints
- refinements
- come in.
- Lesson 1293 — Refinements and Custom ValidationLesson 1305 — Transforming and Refining Inferred Types
- RefObject
- For DOM element references (read-only `.
- Lesson 1521 — Typing useRef for DOM Elements and Mutable Values
- RefType
- is what the ref points to (usually an `HTMLElement`), and **PropsType** defines the component's props.
- Lesson 1527 — Typing forwardRef for Ref-Forwarding Components
- Regular generic type
- Takes types, returns types (`Array<number>`)
- Lesson 1485 — What Are Higher-Kinded Types?
- Remember maintenance
- Code is read far more than it's written.
- Lesson 1516 — Prioritize Developer Experience Over Perfect Types
- remembers
- what type you passed in and carries it through to the return type.
- Lesson 527 — Introducing Type ParametersLesson 1432 — The build() Method and Final Type Inference
- remove
- it using the minus sign:
- Lesson 725 — Removing readonly with MinusLesson 741 — Adding and Removing readonly with + and -Lesson 745 — Making All Properties Mutable
- Reorder overload signatures
- Put more specific signatures before general ones
- Lesson 1628 — Function Overload Conflicts
- Repeated narrowing
- The same variable checked multiple times in different ways
- Lesson 1709 — Control Flow Analysis Overhead
- Repeated patterns
- indicating the same type being checked many times
- Lesson 1729 — Identifying Hot Types in Traces
- ReqBody
- **Request body type** — what comes from `req.
- Lesson 1531 — Typing Request Body and Query in Express
- ReqQuery
- **Query string type** — what comes from `req.
- Lesson 1531 — Typing Request Body and Query in Express
- Request metadata
- Store request IDs, IP addresses, or headers for logging and tracing.
- Lesson 1545 — Context Typing for Procedures
- Require explicit invocation
- (user clicks a button)
- Lesson 1561 — What Distinguishes Queries from Mutations
- Requirements are exploratory
- You're prototyping or experimenting with an unfamiliar problem space
- Lesson 1326 — Type-First vs Code-First Trade-offs
- Requirements are well-understood
- You're building a known pattern (like a REST API client) where the shape is clear upfront
- Lesson 1326 — Type-First vs Code-First Trade-offs
- Requirements evolve
- New features stretch your type assumptions in directions you never anticipated
- Lesson 1695 — Maintainability Over Time
- requires
- you to explicitly specify an `outDir`.
- Lesson 1226 — outDir and rootDir in Composite ProjectsLesson 1289 — Optional and Nullable FieldsLesson 1673 — noImplicitAny as First Defense
- ResBody
- Response body type (rarely used directly in request typing)
- Lesson 1531 — Typing Request Body and Query in Express
- ReScript
- ) compiles to JavaScript, just like TypeScript.
- Lesson 24 — ReasonML and ReScript: OCaml-Based Alternatives
- Resolve union distributions
- across inferred types
- Lesson 1448 — Performance Considerations with Complex infer
- Respects dependencies
- , rebuilding downstream projects when upstream ones change
- Lesson 1230 — Watch Mode with Project References
- Responsiveness
- – How fast your IDE provides autocomplete, diagnostics, and navigation
- Lesson 1790 — Performance and Scalability Focus
- REST
- , you think in terms of **resources** and **HTTP verbs**.
- Lesson 1552 — RPC vs REST: The Conceptual Shift
- rest parameters
- let you capture all remaining arguments into an array using the `.
- Lesson 260 — Rest Parameters BasicsLesson 267 — Rest Parameters vs Array ParametersLesson 1394 — Variadic Tuples vs Rest Parameters
- Result
- Smaller bundles and better tree-shaking.
- Lesson 522 — Bundle Size and Tree-ShakingLesson 594 — Generic Result/Either TypesLesson 951 — Generic Constraints and neverLesson 1685 — Naming Conventions That Clarify
- Return `any`
- You're saying "I don't know what this is, but **I trust you to know better**.
- Lesson 909 — Return Types: When Each Makes Sense
- Return `unknown`
- You're saying "I don't know what this is, and **you must check before using it**.
- Lesson 909 — Return Types: When Each Makes Sense
- Return concrete types
- from functions rather than exposing generic internals
- Lesson 1482 — Library Boundaries and Type Complexity
- Return result types
- when validation failure is a normal flow (bad user input, optional fields)
- Lesson 931 — Error Handling When Validation Fails
- return type
- .
- Lesson 617 — Generic Memoization and CachingLesson 955 — The Basic Exhaustive Check Pattern
- Return type `never`
- The function never returns normally—it always throws.
- Lesson 956 — Creating an assertNever Helper
- Return type annotation
- `: string` after the parentheses declares what the function returns.
- Lesson 236 — Function Type Syntax
- Return type dependencies
- occur when your function's return type changes based on how input type parameters relate to each other.
- Lesson 545 — Return Type Dependencies
- Return types
- of exported functions
- Lesson 160 — Inference Across Module BoundariesLesson 1784 — Decorator Standardization Progress
- Returning Result Types
- Lesson 931 — Error Handling When Validation Fails
- Returns
- either the branded type or signals failure (via `null`, throwing, or a Result type)
- Lesson 1365 — Combining Validation with Types
- reusability
- , **readability**, and **maintenance**.
- Lesson 294 — Anonymous vs Named Object TypesLesson 1652 — Breaking Down Large Unions into Semantic Groups
- Reusable safety
- Once typed, many files benefit immediately
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- reverse mapping
- (looking up an enum member's name from its value), but literal unions cannot provide this feature because they don't exist at runtime.
- Lesson 481 — Literal Unions vs Enums: Trade-offsLesson 489 — Reverse Mapping in Numeric EnumsLesson 510 — String Enums Lack Reverse Mapping
- Reversibility
- If a migration approach isn't working, you've only invested hours or days, not months.
- Lesson 1591 — The Gradual Migration Philosophy
- Risk distribution
- Converting thousands of files at once creates a massive changeset where any mistake can break production.
- Lesson 1591 — The Gradual Migration Philosophy
- Rollup
- specializes in library bundling.
- Lesson 1234 — Bundlers: Webpack, Rollup, esbuild, and OthersLesson 1241 — Vite and Modern Bundler WorkflowsLesson 1258 — When to Enable isolatedModules
- RPC
- (Remote Procedure Call), you think in terms of **functions you're calling**.
- Lesson 1552 — RPC vs REST: The Conceptual Shift
- Run conditional setup logic
- that doesn't fit in a simple assignment
- Lesson 1059 — Static Blocks for Initialization
- Runtime checks
- Accept looser types and validate at runtime when type gymnastics aren't worth it
- Lesson 652 — When Conditional Constraints Become Too ComplexLesson 662 — When Constraint Composition Becomes Overengineering
- Runtime code
- the JavaScript that actually executes in your browser or Node.
- Lesson 1463 — What Is Type-Level Programming?
- Runtime confusion
- Code checking enum values must handle both numbers and strings, complicating logic.
- Lesson 492 — Heterogeneous Enums (Mixed Types)
- Runtime environment extensions
- (like custom properties on `window`)
- Lesson 1172 — What Global Augmentation Means
- Runtime errors
- are like factual mistakes that only become obvious *after* someone reads your essay—by then, it's already published and embarrassing.
- Lesson 2 — Runtime Errors vs Compile-Time Errors
- Runtime logic
- The function body uses a simple regex replace to substitute parameter values
- Lesson 856 — Building URL Builder Functions
- Runtime safety
- If somehow a value slips through (maybe due to unsafe casts elsewhere), you get a clear error message instead of silent misbehavior.
- Lesson 956 — Creating an assertNever HelperLesson 1526 — Typing Context Providers with createContext
- Runtime validation
- Your code checks data when it actually executes
- Lesson 1298 — The Problem: Duplication Between Runtime and Type ChecksLesson 1310 — The End-to- End Type Safety VisionLesson 1534 — Path Parameters and Validation in HonoLesson 1542 — Input Validation with Zod SchemasLesson 1557 — Input Validation with Zod Integration
- Runtime values
- in `STATUSES` for iteration or validation.
- Lesson 482 — Extracting Union Members as Values
S
- Safe narrowing
- Inside the `if`, TypeScript knows `data` is `T`, so the return is type-safe
- Lesson 934 — Generic parseResponse Helper Function
- Safe to retry
- automatically on failure
- Lesson 1561 — What Distinguishes Queries from MutationsLesson 1562 — tRPC query() Method Basics
- safety
- .
- Lesson 35 — Build Tools and TypeScriptLesson 244 — Explicitly Typing Callback ParametersLesson 629 — Constraints and Type InferenceLesson 1420 — Combining const with Constraints
- Scenario 2: Empty arrays
- Lesson 1520 — Typing useState with Generic Type Arguments
- Scenario 3: Incorrect types
- Lesson 185 — Inference with Third-Party Libraries
- Script mode (global)
- All declarations are automatically available everywhere without imports.
- Lesson 1158 — The global Scope in .d.ts Files
- Scripts and automation
- work best with `ts-node` or `tsx`.
- Lesson 75 — Choosing the Right Execution Method for Your Use Case
- Scripts and tooling
- Build scripts or utilities that aren't part of your application.
- Lesson 1751 — excludeFiles and IDE Performance
- Search Your Codebase
- Lesson 1678 — Auditing Codebases for any Usage
- Second assertion
- (`as Engine`): `unknown` can be asserted to any type
- Lesson 995 — Overriding Incompatible Types
- Second assertion (`as TargetType`)
- From that blank slate, you assert it's whatever you want
- Lesson 994 — The unknown Middle Step
- Second pass
- Implementation reveals emails can be optional for guest users:
- Lesson 1329 — Refining Types Through Iteration
- Semantic clarity
- Your API contract explicitly shows what reads vs.
- Lesson 1563 — tRPC mutation() Method Basics
- Separate adoption period
- Teams can test it independently without enabling all of `strict`
- Lesson 1194 — Future Additions to strict
- Separate Repositories
- If your frontend and backend live in different repos with separate deployment cycles, sharing the router type becomes complex.
- Lesson 1559 — Trade-offs: When tRPC Fits vs Doesn't
- Separate validation
- (TypeScript): `tsc --noEmit` — checks types without outputting files
- Lesson 1235 — Type-Checking vs Transpilation Separation
- Server receives validated input
- with full type information
- Lesson 1544 — Mutation Procedures with Input Types
- Server side
- You define a procedure with input validation (using Zod or similar) and return a typed value
- Lesson 1541 — tRPC Procedure Basics
- Set minimum description lengths
- to ensure meaningful explanations
- Lesson 901 — Linting Suppression Comments
- shared state
- from accidental mutation
- Lesson 673 — When to Use Each UtilityLesson 1056 — Static Properties Basics
- Shared type packages
- Publish types to npm (versioning complexity, still uses type assertions at runtime boundaries)
- Lesson 1551 — What tRPC Solves: The Type-Safety Gap
- Shows helpful hints
- Hover over something to see what type it is and how to use it
- Lesson 4 — Autocomplete and IntelliSense Benefits
- Signal intent
- Make it obvious that something is purely for types
- Lesson 1106 — export type for Type-Only Exports
- Simple primitive types
- the "leaf nodes" of your type tree
- Lesson 1466 — Base Cases and Termination Conditions
- Simpler constraints
- Use basic `extends` checks and handle complexity in the function body
- Lesson 652 — When Conditional Constraints Become Too Complex
- Simpler mental model
- A union like `"success" | "error" | "pending"` is exactly what it looks like—a choice between strings.
- Lesson 515 — Community Preference for Unions
- Simplified type representations
- rather than fully expanded aliases
- Lesson 1791 — Better Error Messages and Developer Experience
- Simplify incrementally
- Comment out parts of your complex type and add them back one piece at a time until the error appears.
- Lesson 1691 — Debugging Complex Generic Errors
- Simplify nested infer
- by breaking complex conditionals into smaller, named helper types.
- Lesson 1448 — Performance Considerations with Complex infer
- Simplify the recursive case
- Avoid combining recursion with complex mapped types or conditional logic
- Lesson 1714 — Recursive Type Aliases and Stack Depth
- Single compilation
- You're not using `isolatedModules` (or you've enabled `preserveConstEnums` as a workaround)
- Lesson 506 — When to Use const enums
- Single point of change
- Adding a new payment type requires modifying this central union, creating merge conflicts and forcing recompilation of distant code.
- Lesson 1658 — The Module Boundary Smell
- single source of truth
- (often your database schema or API contract) and derive all other types from it.
- Lesson 1310 — The End-to-End Type Safety VisionLesson 1514 — Use Code Generation for Complex PatternsLesson 1535 — Zod Validators with Hono MiddlewareLesson 1553 — The Single Source of Truth PrincipleLesson 1583 — Defining zodios API Contracts
- Single Use Context
- Lesson 1369 — When Opaque Types Add Value
- Single-owner types
- If you control the entire interface, just define it once completely
- Lesson 369 — When to Leverage Declaration Merging
- Size and longevity matter
- For a quick prototype or one-off script, plain JavaScript might be faster.
- Lesson 30 — When to Choose TypeScript Over Alternatives
- Slow editor responsiveness
- when hovering over types
- Lesson 1448 — Performance Considerations with Complex infer
- Slow IDE autocomplete
- That spinning wheel when you type a dot
- Lesson 1477 — Compile-Time Performance ImpactLesson 1715 — Mapped Types Over Large Object Types
- Slow IDE responsiveness
- when hovering over types
- Lesson 839 — Performance and Complexity Considerations
- Slow scenarios
- Lesson 1707 — Contextual Typing Performance
- Slow to compile
- The compiler must recursively evaluate complex type expressions, dramatically increasing compilation time
- Lesson 1503 — The Complexity Tax of HKT Simulation
- Slow type narrowing
- each `typeof`, `in`, or `===` check tests against all members
- Lesson 1741 — Break Large Union Types into Smaller Chunks
- Slower to compile
- Complex type operations impact TypeScript's performance
- Lesson 1483 — The Principle of Least Type Power
- Slowest files
- Which source files consumed the most compiler time
- Lesson 1730 — Using @typescript/analyze-trace CLI
- Sluggish error checking
- red squiggles appearing slowly or disappearing incorrectly
- Lesson 1505 — IDE Performance Degradation
- Small to medium codebases
- (under 10,000 lines) can benefit from all-at-once conversion.
- Lesson 1613 — The All-at-Once Approach: Risks and RewardsLesson 1649 — When Automation Helps vs Manual Migration
- smart constructor
- pattern: make the type impossible to construct directly, and force all creation through a validation function.
- Lesson 1344 — Temporal Constraints in TypesLesson 1363 — Smart Constructor Functions
- Smart Constructor Pattern
- solves this: you write a factory function that:
- Lesson 1352 — Smart Constructor Pattern
- smart constructors
- to prevent type misuse.
- Lesson 1359 — Tradeoffs and ErgonomicsLesson 1364 — Private Constructors Pattern
- Smarter Error Messages
- Lesson 1782 — Better Error Messages and Developer Experience
- Snapshot Testing Type Definitions
- Lesson 1321 — Testing End-to-End Type Safety
- Solidifying the type checker
- so it could reliably catch null and undefined errors
- Lesson 15 — TypeScript 0.8 Through 1.0
- Solo throwaway projects
- Building a one-off tool just for yourself that you'll use once?
- Lesson 12 — When Static Typing Isn't Worth It
- Solution
- Either add the property to your type or use a different type:
- Lesson 337 — Common Spread Pitfalls and SolutionsLesson 543 — Generic Arrow Functions
- Solutions
- Lesson 1631 — Build Times Exploding
- Sound typing focus
- Flow prioritizes catching *all* type errors (even if it means rejecting valid code)
- Lesson 23 — Flow: Facebook's Type Checker
- Soundness
- means the type system guarantees your code will never have certain categories of runtime errors.
- Lesson 27 — Hegel: A Stronger Type System for JavaScript
- Specific literal types
- exact values that signal completion
- Lesson 1466 — Base Cases and Termination Conditions
- Specification Alignment
- As ECMAScript evolves, TypeScript occasionally adjusts to match JavaScript behavior, even if it breaks existing patterns.
- Lesson 1785 — Community Feedback and Breaking Changes
- speed
- over **safety**.
- Lesson 35 — Build Tools and TypeScriptLesson 84 — The --skipLibCheck Flag: Skipping node_modules Types
- Split by domain
- Separate shared utilities, core business logic, and application layers into distinct projects
- Lesson 1753 — Workspace Recommendations for Speed
- Split concerns
- One project handles data models, another handles business logic — eliminate back-references
- Lesson 1228 — Circular References Between Projects
- Split the function
- Sometimes JavaScript functions do too many things; migration is a chance to separate concerns
- Lesson 1628 — Function Overload Conflicts
- spreads
- like a virus through your codebase.
- Lesson 877 — any Spreads Through Your CodebaseLesson 1723 — The any Pollution Performance Hit
- Stabilizing the compiler
- to ensure predictable compile-time error checking
- Lesson 15 — TypeScript 0.8 Through 1.0
- Stable union types
- The union rarely changes, so the maintenance benefit of exhaustiveness is minimal
- Lesson 426 — When Exhaustiveness Isn't Needed
- Stable, battle-tested utilities
- that rarely change and work perfectly
- Lesson 1602 — When to Stop and Ship
- Stack Overflow
- with the `typescript` tag for searchable Q&A
- Lesson 39 — Community Resources and Learning
- Stacks multiple failures
- when outer types depend on inner inferred types
- Lesson 1476 — Debugging Complex Type Errors
- Stage 0 (Strawperson)
- An informal idea, just a proposal document
- Lesson 1756 — Stage 0-4 Process and TypeScript Timing
- Stage 0-1 (Strawperson/Proposal)
- TypeScript rarely touches these.
- Lesson 1783 — ECMAScript Alignment Strategy
- Stage 1 (Proposal)
- Problem identified, high-level API sketched
- Lesson 1756 — Stage 0-4 Process and TypeScript Timing
- Stage 2
- features if they're very stable and highly anticipated (decorators being a famous example).
- Lesson 1756 — Stage 0-4 Process and TypeScript Timing
- Stage 2 (Draft)
- Formal specification text written, syntax decided
- Lesson 1756 — Stage 0-4 Process and TypeScript TimingLesson 1783 — ECMAScript Alignment Strategy
- Stage 3 (Candidate)
- Spec complete, awaiting implementation feedback
- Lesson 1756 — Stage 0-4 Process and TypeScript TimingLesson 1783 — ECMAScript Alignment Strategy
- Stage 4 (Finished)
- Tested in browsers, ready for the next ECMAScript release
- Lesson 1756 — Stage 0-4 Process and TypeScript TimingLesson 1783 — ECMAScript Alignment Strategy
- Standalone function declarations
- Regular function declarations don't receive contextual hints—they exist independently.
- Lesson 188 — Contextual Typing Not Applied Everywhere
- Standard mode
- (`tsc`): Compile once and stop
- Lesson 76 — Understanding Compilation Modes: Build vs Watch vs Project
- Start minimal
- only type the functions you actually use, then expand as needed
- Lesson 1147 — Typing Third-Party Libraries
- State snapshots
- where you want compile-time guarantees nothing mutates
- Lesson 813 — The DeepReadonly Pattern
- Static typing
- means your code's types are checked *before* the program runs.
- Lesson 1 — What is Static Typing?Lesson 2 — Runtime Errors vs Compile-Time Errors
- Step 1: allowJs only
- TypeScript compiles your `.
- Lesson 1612 — Combining allowJs, checkJs, and Incremental Migration
- Storage and caching
- Lesson 1676 — Replacing any with unknown for Safe Migration
- Strictness Expansion
- New flags like `noUncheckedIndexedAccess` are opt-in, but they reveal problems in existing code when enabled.
- Lesson 1785 — Community Feedback and Breaking Changes
- string
- describing what type that value is at runtime.
- Lesson 190 — The typeof Operator in JavaScriptLesson 312 — String vs Number Index Signatures
- String Enums
- are *nominal* types at the type level — only actual enum members can be assigned:
- Lesson 518 — Type Safety: Enums vs Unions
- string index signature
- (`[key: string]: Type`) allows any string key—perfect for objects where you'll use property names like `user.
- Lesson 312 — String vs Number Index SignaturesLesson 636 — keyof with Index Signatures
- string literal types
- , and they look like this:
- Lesson 458 — String Literal Types SyntaxLesson 712 — Uppercase, Lowercase, Capitalize, Uncapitalize String Utilities
- string literal union
- combines multiple string literals with the `|` operator to define a type that can only be one of those exact strings.
- Lesson 479 — String Literal Unions as Lightweight EnumsLesson 682 — Record with String Literal KeysLesson 719 — keyof and Property Iteration
- string literal unions
- and **enums** let you restrict values to a specific set of options, but they work differently under the hood.
- Lesson 481 — Literal Unions vs Enums: Trade-offsLesson 512 — Enums Don't Interop WellLesson 726 — Mapping Over Literal Types
- String manipulations
- (Uppercase, Lowercase, Capitalize, Uncapitalize)
- Lesson 716 — The Full Standard Library Reference
- String template literal types
- which are expensive to process
- Lesson 1738 — Cache Expensive Mapped Type Results
- String-Literal Unions
- are *structural* — any matching string literal works:
- Lesson 518 — Type Safety: Enums vs Unions
- Stronger guarantees
- The type system catches more errors at compile time
- Lesson 24 — ReasonML and ReScript: OCaml-Based Alternatives
- structural
- type systems (like TypeScript), types are compatible based on their *shape*, not their name.
- Lesson 355 — Type Aliases Are Not NominalLesson 1486 — Why TypeScript Lacks True HKTs
- Structural flexibility
- types describe shapes, not rigid contracts
- Lesson 1486 — Why TypeScript Lacks True HKTs
- structural typing
- (also called "duck typing").
- Lesson 1348 — Structural vs Nominal TypingLesson 1703 — Structural Type Checking Mechanics
- Structurally
- a string (at runtime, it *is* just a string)
- Lesson 1362 — Simulating Opaque Types with Branding
- Structure and shape
- (objects, arrays, basic unions)
- Lesson 1509 — Embrace Runtime Checks Over Type Gymnastics
- Sublime Text
- Restart the LSP-typescript plugin through the Command Palette
- Lesson 1752 — Restart Language Service When Stuck
- substitute
- `A` properly.
- Lesson 1497 — Type-Level Apply FunctionsLesson 1702 — Constraint Solving and UnificationLesson 1749 — Complex Types and Autocomplete Lag
- Success case
- `{ success: true, data: T }` — the parsed and validated data
- Lesson 1294 — Safe Parsing with .safeParse
- Suppressions stand out
- in pull requests rather than hiding silently
- Lesson 901 — Linting Suppression Comments
- swc
- have TypeScript compilation built directly into their bundling process.
- Lesson 35 — Build Tools and TypeScriptLesson 1238 — esbuild and swc: Fast Type StrippingLesson 1253 — What isolatedModules DoesLesson 1258 — When to Enable isolatedModules
T
- TC39
- (Technical Committee 39) is the standards body responsible for evolving JavaScript through the ECMAScript specification.
- Lesson 1755 — TC39 and ECMAScript: The FoundationLesson 1756 — Stage 0-4 Process and TypeScript Timing
- Team composition changes
- The person who understands your nested `infer` chains leaves; junior developers join
- Lesson 1695 — Maintainability Over Time
- Team consistency
- Everyone must satisfy the same type rules, regardless of their local setup.
- Lesson 1263 — Why Type-Check in CI
- Team Coordination
- When multiple developers work on interconnected features, agreed-upon types serve as contracts.
- Lesson 1333 — When Type-First Design Pays Off
- Team policy requires consistency
- and you have the time to enforce it
- Lesson 1602 — When to Stop and Ship
- Team productivity
- A six-month freeze where no features ship while you rewrite everything?
- Lesson 1591 — The Gradual Migration Philosophy
- Team velocity
- developers can keep shipping features while migration happens
- Lesson 1612 — Combining allowJs, checkJs, and Incremental Migration
- Team velocity drops
- When junior developers fear touching type-heavy modules, or PRs stall on type refinement debates, the safety isn't worth the collaboration cost.
- Lesson 1508 — Diminishing Returns on Type Safety
- Teams enforce consistent standards
- for when suppressions are acceptable
- Lesson 901 — Linting Suppression Comments
- Teams with migration expertise
- who've done this before can move quickly and anticipate common pitfalls.
- Lesson 1613 — The All-at-Once Approach: Risks and Rewards
- Template literal combinations
- Crossing two 10-member string unions creates 100 possibilities
- Lesson 1472 — Limits of Type-Level Computation
- Template literal explosions
- multiply string combinations geometrically
- Lesson 1484 — Recognizing When You've Gone Too Far
- Template Literal Types
- allowed you to create types from string patterns—imagine being able to enforce that a string must be formatted exactly like `"user_123"` or `"admin_456"` at the type level.
- Lesson 18 — TypeScript 4.x: Refinement and PerformanceLesson 819 — Basic Template Literal SyntaxLesson 830 — The Four Built-In String Manipulation TypesLesson 840 — Mapping Keys to Template Literal TypesLesson 841 — Dynamic Property Name GenerationLesson 842 — Prefixing and Suffixing Object KeysLesson 843 — The Getters PatternLesson 844 — The Setters Pattern (+5 more)
- template literals
- (backticks), which let you embed expressions inside strings:
- Lesson 88 — The string TypeLesson 848 — Nested Property Path Generation
- Temporal API
- is a Stage 3 TC39 proposal that will introduce a suite of *immutable*, strongly-typed objects for working with dates and times.
- Lesson 1761 — Temporal API and Date Type Safety
- temporary
- .
- Lesson 897 — @ts-nocheck for Entire FilesLesson 899 — Acceptable Use Cases for Suppressions
- Temporary Migration States
- Lesson 899 — Acceptable Use Cases for Suppressions
- Temporary third-party type bugs
- When a library has incorrect types but you need to ship today.
- Lesson 896 — When @ts-expect-error Is Preferred
- Terminal 2
- `tsc --noEmit --watch` runs continuously, type-checking without generating files
- Lesson 1240 — Running tsc in Parallel with Bundling
- Terminal methods
- (execution, retrieval) return actual results and end the chain
- Lesson 1078 — Mixing Chainable and Non-Chainable Methods
- Test artifacts
- `coverage`, `__snapshots__`—type-checking coverage reports is pointless.
- Lesson 1751 — excludeFiles and IDE Performance
- Test files
- where you're intentionally checking invalid states
- Lesson 894 — What Are Type Suppression CommentsLesson 1593 — Choosing Your First Files
- Test readability
- improves by focusing only on what matters
- Lesson 1005 — Mocking and Testing Scenarios
- Test with assignments
- Try assigning a literal object to your intersection type—TypeScript will complain at the exact conflicting property.
- Lesson 448 — Deep Property Conflicts
- Testing compile time
- with `tsc --diagnostics` on large codebases
- Lesson 764 — Performance Considerations with as
- Testing frameworks
- that provide type-safe mocking
- Lesson 1796 — Long-Term Vision: TypeScript as a Platform
- Testing is impossible
- you can only verify types compile, not why they work
- Lesson 1480 — The Maintenance Burden of Clever Types
- Testing the waters
- Let your team experience TypeScript's safety without file renames
- Lesson 1604 — checkJs: Type-Checking JavaScript Without Conversion
- Testing/mocking
- Creating fake objects that don't fully implement interfaces
- Lesson 995 — Overriding Incompatible Types
- These assignments fail
- Lesson 97 — Assignability Between Primitives
- These assignments work
- Lesson 97 — Assignability Between Primitives
- Think of it like
- spreading objects is like painting layers on a canvas — later layers completely cover earlier ones, both in value and type.
- Lesson 331 — Property Override Order and Type MergingLesson 1137 — When You Need a .d.ts File
- Third pass
- You realize you need to distinguish between guests and registered users:
- Lesson 1329 — Refining Types Through Iteration
- Third-party API responses
- Even documented APIs can change or return errors in unexpected formats.
- Lesson 1282 — When Type Assertions Are Acceptable
- Third-party code
- Working with untyped libraries before types are available
- Lesson 126 — Introduction to any: The Opt-Out TypeLesson 1604 — checkJs: Type-Checking JavaScript Without Conversion
- Third-party code integration
- is blocking your migration path
- Lesson 1004 — Progressive Migration Scenarios
- Third-party dependencies
- Untyped libraries need `@types` packages or custom declarations
- Lesson 1594 — The .js to .ts Rename Strategy
- Third-party integrations
- using GraphQL (graphql-codegen)
- Lesson 1590 — Hybrid Strategies: Mixing Approaches
- Third-party JavaScript libraries
- ship declaration files so TypeScript users get type safety
- Lesson 1124 — What Are Declaration Files (.d.ts)
- Third-party libraries
- You don't control the source, but need to reference its types
- Lesson 707 — When These Utilities Save RepetitionLesson 936 — unknown for External Data Entry Points
- Third-party library quirks
- A library's types say something might be null, but you know it won't be in your usage
- Lesson 985 — Non-Null Assertions with !Lesson 1190 — The Cost of strict: False Positives
- This is frustrating
- maybe you're passing through options to an underlying library that *does* use `debug`.
- Lesson 329 — Common Gotchas with Options Objects
- This is wrong
- Type assertions are purely a compile-time instruction that tells TypeScript: "Trust me, I know better than you about this value's type.
- Lesson 982 — Assertions Are Not Casts
- throw an error
- or **run forever**.
- Lesson 135 — Functions That Return neverLesson 889 — Assertion Functions with unknown
- Throw errors
- when invalid data is a bug or truly unexpected
- Lesson 931 — Error Handling When Validation Fails
- Throwing Descriptive Errors
- Lesson 931 — Error Handling When Validation Fails
- Throws an error
- if invalid
- Lesson 934 — Generic parseResponse Helper FunctionLesson 941 — unknown in Type-Safe Validators
- Time in each phase
- Parse time, bind time, check time, emit time
- Lesson 1725 — Using --extendedDiagnostics for Build Metrics
- Tiny scripts
- A 20-line script that renames files or processes a CSV?
- Lesson 12 — When Static Typing Isn't Worth It
- Tooling Limitations
- Lesson 899 — Acceptable Use Cases for Suppressions
- Top-down
- Begin with entry points or high-level modules and work your way down to dependencies, using type assertions or stubs when reaching unconverted code.
- Lesson 1614 — The File-by-File Incremental Strategy
- Top-down inference
- (also called **contextual typing**) starts with an expected type based on where a value is being used, then flows that type information downward into the expression.
- Lesson 1700 — Type Inference Flow: Bottom-Up and Top-Down
- Top-down migration
- means starting with entry points like `main.
- Lesson 1599 — The Bottom-Up vs Top-Down Decision
- Top-level exports
- Declarations marked with `export` that other files can import
- Lesson 1126 — Structure of a Basic Declaration File
- Total compile time
- Wall-clock time from start to finish
- Lesson 1731 — The --diagnostics Flag for Quick Summaries
- Track multiple inference sites
- and their constraints
- Lesson 1448 — Performance Considerations with Complex infer
- Tracking progress isn't optional
- it's the difference between a successful migration and an abandoned half-typed codebase.
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- Trade-off
- You lose reverse mapping, iteration, and some tooling compatibility, but you gain the performance benefits of literal values.
- Lesson 522 — Bundle Size and Tree-ShakingLesson 813 — The DeepReadonly PatternLesson 1237 — Bundler Loaders: ts-loader and babel-preset-typescriptLesson 1648 — Alternative Tools: dts-gen and Others
- Tradeoff
- You might miss some type errors if your dependencies have incorrect or conflicting type definitions, but this is rare and the performance gain is almost always worth it.
- Lesson 84 — The --skipLibCheck Flag: Skipping node_modules Types
- Transform tuple structures
- while maintaining type relationships
- Lesson 1394 — Variadic Tuples vs Rest Parameters
- transforming
- those interfaces into new shapes.
- Lesson 368 — Hybrid Approaches: Interfaces + Type AliasesLesson 738 — Preserving vs Transforming Union Members
- Translation dictionaries
- `{ "en": "Hello", "es": "Hola", "fr": "Bonjour" }` — you don't know every language code upfront
- Lesson 310 — What Index Signatures Solve
- Transpilation
- converting TypeScript into JavaScript
- Lesson 1231 — What tsc Does: Type-Checking and TranspilationLesson 1235 — Type-Checking vs Transpilation Separation
- Transpiling
- (removing types and transforming syntax) to JavaScript
- Lesson 1773 — Impact on the TypeScript Compiler
- Tree-shakable by default
- Since unions don't generate code, there's nothing to tree-shake.
- Lesson 515 — Community Preference for Unions
- Tree-shaking
- Unused members disappear in bundles
- Lesson 486 — When to Graduate to Real EnumsLesson 511 — No Tree-Shaking for EnumsLesson 522 — Bundle Size and Tree-ShakingLesson 1097 — Why type-only imports matter for bundlers
- Triggers cascading checks
- (changing it forces rechecking many dependents)
- Lesson 1729 — Identifying Hot Types in Traces
- Truly dynamic values
- Rare cases where the type genuinely can't be known
- Lesson 126 — Introduction to any: The Opt-Out Type
- Trust
- Published libraries are usually already type-checked by their maintainers
- Lesson 84 — The --skipLibCheck Flag: Skipping node_modules Types
- Trust your team
- Developers understand their domain.
- Lesson 1516 — Prioritize Developer Experience Over Perfect Types
- ts-rest
- lets you define a REST API contract once, then use it on both client and server with automatic inference—no build step required.
- Lesson 1315 — Type-Safe REST with ts-restLesson 1581 — The End-to-End Type Safety LandscapeLesson 1584 — ts-rest: Contract-First REST APIsLesson 1589 — When to Choose Each Approach
- tsc
- (the TypeScript compiler) separately, in parallel, *only* for type-checking using the `--noEmit` flag.
- Lesson 1241 — Vite and Modern Bundler WorkflowsLesson 1246 — When Libraries Need Declaration Files Only
- tuple
- , on the other hand, is a fixed-length array where TypeScript knows **exactly** how many elements there are and what type each position holds.
- Lesson 114 — Fixed-Length Arrays vs TuplesLesson 116 — What Tuples Are and When to Use ThemLesson 124 — Tuples vs ArraysLesson 151 — Tuple Inference vs Array InferenceLesson 704 — ConstructorParameters: Extract Constructor ArgsLesson 1372 — Tuple Type Inference from LiteralsLesson 1437 — Extracting Function Parameter Types
- Tuple types
- instead of arrays (when order and length matter)
- Lesson 1416 — const vs Normal Type Parameters
- Tuples
- are for heterogeneous, structured data where:
- Lesson 124 — Tuples vs ArraysLesson 1370 — Tuple Types vs Array Types
- Turborepo
- , **Nx**, and **pnpm workspaces** all take advantage of TypeScript's project reference system:
- Lesson 38 — Monorepo Tooling and TypeScript
- Twitter/X
- where TypeScript team members and community experts share tips
- Lesson 39 — Community Resources and Learning
- type alias
- is simply a name you create for any type.
- Lesson 348 — What Is a Type Alias?Lesson 379 — Computed Properties: Type Aliases Are More FlexibleLesson 1744 — Prefer interface Over type for Object Shapes
- type aliases
- for derived types, unions, intersections, and complex computed types.
- Lesson 368 — Hybrid Approaches: Interfaces + Type AliasesLesson 1138 — Basic Declaration File Structure
- type annotations
- that give you compile-time type checking without converting your `.
- Lesson 1635 — Basic JSDoc Type SyntaxLesson 1766 — Keeping TypeScript Aligned with JavaScript
- Type Annotations Proposal
- is a TC39 proposal to add type syntax directly to JavaScript — but with a crucial twist: **JavaScript engines would completely ignore the types at runtime**.
- Lesson 1767 — What the Type Annotations Proposal IsLesson 1771 — Type Checking Still Requires TypeScriptLesson 1775 — Challenges and Controversies
- Type assertions
- (though this defeats the safety purpose)
- Lesson 887 — Basic Operations on unknown ValuesLesson 1769 — Syntax That Would Be Standardized
- Type checking
- Any value can be passed in
- Lesson 179 — Implicit any from Untyped ParametersLesson 1726 — Reading the Diagnostics Output
- Type Checking Phase
- Only after the structure is understood does TypeScript validate that types are used correctly— checking assignments, function calls, property access, and all type relationships.
- Lesson 1699 — TypeScript's Two-Phase Compilation Model
- Type checking seems wrong
- after major dependency changes
- Lesson 1752 — Restart Language Service When Stuck
- type constructors
- types that take other types as parameters:
- Lesson 1485 — What Are Higher-Kinded Types?Lesson 1497 — Type-Level Apply Functions
- type definition
- .
- Lesson 1316 — Deriving Frontend Types from Backend SchemasLesson 1570 — The Router Type: AppRouter as Source of Truth
- Type definitions
- Interfaces, type aliases, and other type constructs
- Lesson 1126 — Structure of a Basic Declaration File
- type guard
- in TypeScript.
- Lesson 111 — Array Type Guards and NarrowingLesson 202 — Equality Narrowing with ===Lesson 211 — The in Operator for Property CheckingLesson 224 — Narrowing with Type PredicatesLesson 401 — Array.isArray for Array vs Non-ArrayLesson 916 — Array.isArray for Array NarrowingLesson 1276 — Type Guards for Response Validation
- type guards
- come in—they're runtime checks that tell TypeScript "I've verified what this is now, so treat it accordingly.
- Lesson 102 — Type Guards for PrimitivesLesson 811 — Creating Type Guards as Types
- Type has conceptual meaning
- "User", "Config", "Response" communicate intent
- Lesson 357 — Type Aliases vs Inline Types
- Type inference
- means TypeScript examines your code and determines what types your variables should have — without you explicitly writing type annotations.
- Lesson 141 — What Is Type Inference?Lesson 1535 — Zod Validators with Hono MiddlewareLesson 1555 — No Code Generation RequiredLesson 1634 — Enabling Type-Checking with checkJs
- type information
- for code that doesn't have it.
- Lesson 1125 — When You Need Declaration FilesLesson 1166 — Adding New Exports to a Module
- Type information on hover
- Lesson 36 — Editor Support and Language ServicesLesson 1747 — Why IDE Performance Matters
- Type instantiation depth
- measures how many nested layers deep the compiler goes when resolving a single generic type.
- Lesson 1711 — Understanding Type Instantiation Depth
- Type is complex
- Nested objects or unions are easier to understand when named
- Lesson 357 — Type Aliases vs Inline Types
- type narrowing
- you're proving to TypeScript what the value actually is.
- Lesson 132 — Narrowing unknown with typeofLesson 189 — What Is Type Narrowing?
- type parameter
- (written in angle brackets) to capture the type you pass in:
- Lesson 538 — Your First Generic FunctionLesson 596 — Generic Builder PatternLesson 1274 — Generic Wrapper Functions for fetchLesson 1429 — Conditional Method Availability
- type parameters
- with template literal types, you can build powerful string transformation utilities that work across different inputs while maintaining full type safety.
- Lesson 827 — Template Literals in Generic TypesLesson 1528 — Generic Components with Type ParametersLesson 1638 — Generic Functions with JSDoc @template
- Type parameters flow through
- Whatever type `T` is at the call site becomes the return type
- Lesson 609 — The Identity Function Pattern
- type predicate
- is a special return type for functions that tells TypeScript exactly what type a value has when the function returns `true`.
- Lesson 221 — What Type Predicates AreLesson 223 — Type Predicates vs Boolean ReturnsLesson 398 — Type Predicates for Custom NarrowingLesson 918 — Type Predicates for Custom NarrowingLesson 929 — Array Validation from unknown SourcesLesson 1276 — Type Guards for Response Validation
- Type predicate parameter
- `validator: (value: unknown) => value is T` tells TypeScript "if this returns true, narrow to `T`"
- Lesson 934 — Generic parseResponse Helper Function
- Type Predicate Pattern
- takes this further by making conditional types return `true` or `false` literal types — essentially creating compile-time boolean checks that TypeScript can reason about.
- Lesson 806 — The Type Predicate Pattern
- type predicates
- come in—they let you create your own custom type-checking functions that TypeScript understands and trusts.
- Lesson 222 — Basic Type Predicate SyntaxLesson 233 — Assertion Functions vs Type Predicates
- type preservation
- (like returning `T[K]`).
- Lesson 642 — When keyof Constraints Are OverkillLesson 1663 — When Generics Are Better: Type Preservation NeededLesson 1666 — Generic Constraints vs Union Bounds
- Type providers
- solve this by making your schema the single source of truth.
- Lesson 1539 — Type Providers in Fastify for Full Safety
- Type safety
- You can't accidentally add unexpected properties
- Lesson 317 — Index Signatures and Record UtilityLesson 1056 — Static Properties BasicsLesson 1116 — The exports Field for Modern PackagesLesson 1220 — Combining Safety Flags for Maximum ProtectionLesson 1387 — Generic Variadic Tuple FunctionsLesson 1526 — Typing Context Providers with createContext
- Type safety across packages
- No more loose `any` types at package boundaries
- Lesson 1229 — Monorepo Patterns with References
- Type safety is local
- The constraint doesn't propagate through generic flows
- Lesson 1662 — When Unions Are Better: Known Fixed Options
- Type Safety Theater
- Lesson 898 — The Danger of Suppression Comments
- Type System Expressiveness Limits
- Lesson 1015 — When Assertions Are Actually Acceptable
- Type system limitations
- Rare cases where correct runtime code can't be expressed in TypeScript's type system
- Lesson 995 — Overriding Incompatible Types
- Type system surprises
- emerge when implicit behaviors that worked fine in JavaScript suddenly conflict with TypeScript's expectations, and you discover them all at once rather than incrementally.
- Lesson 1613 — The All-at-Once Approach: Risks and Rewards
- Type utility modules
- Dedicated files containing your complex mapped types, conditional types, and type-level functions
- Lesson 1515 — Separate Business Logic from Type Acrobatics
- type variable
- that remembers what you passed in:
- Lesson 531 — Type Parameters vs anyLesson 538 — Your First Generic Function
- Type-checking
- analyzing your code for type errors
- Lesson 1231 — What tsc Does: Type-Checking and TranspilationLesson 1235 — Type-Checking vs Transpilation SeparationLesson 1268 — Type-Checking vs Building in CILesson 1773 — Impact on the TypeScript Compiler
- Type-checking and declaration generation
- (TypeScript's strength)
- Lesson 1247 — Setting emitDeclarationOnly in tsconfig.json
- Type-First
- You define your interfaces, types, and domain models before writing implementation code.
- Lesson 1326 — Type-First vs Code-First Trade-offs
- Type-first annotations
- (Approach 2) are useful when you're implementing a specific function signature or want to reuse the type.
- Lesson 237 — Arrow Function Type Annotations
- Type-level code
- the type system that runs during compilation and then disappears
- Lesson 1463 — What Is Type-Level Programming?
- Type-level function application
- to unwrap the final result
- Lesson 1503 — The Complexity Tax of HKT Simulation
- Type-level programming
- means writing logic that exists *only* in the type system.
- Lesson 1463 — What Is Type-Level Programming?
- Type-level programming patterns
- treating types like functions that compute other types — are essentially off the table.
- Lesson 1640 — JSDoc Limitations vs Native TypeScript
- Type-only imports
- solve this by letting you use types for compile-time checking without affecting the runtime JavaScript at all.
- Lesson 1595 — Type-Only Imports for Existing JS
- Type-Only Packages
- Lesson 1125 — When You Need Declaration FilesLesson 1245 — What emitDeclarationOnly Does
- Type-safe data transformations
- Lesson 942 — When NOT to Use unknown
- Type-safe event systems
- where event names were specific strings
- Lesson 1414 — What const Type Parameters Solve
- Type-safe form submission
- ensures only valid, correctly-typed data reaches your API
- Lesson 1317 — Type Safety in Form Handling
- Type-safe wrappers
- Lesson 700 — Parameters: Extract Function Parameter Types
- Typeclasses
- Interfaces like `Functor`, `Monad`, and `Applicative` that declare operations generically
- Lesson 1502 — Libraries That Use HKT Simulation: fp-ts
- types
- (the categories that describe the data).
- Lesson 93 — Literal Values vs Type NamesLesson 767 — Your First Conditional TypeLesson 1725 — Using --extendedDiagnostics for Build MetricsLesson 1726 — Reading the Diagnostics Output
- Types → API Contract
- Your API handlers use these types for requests and responses
- Lesson 1310 — The End-to-End Type Safety Vision
- Types the response
- automatically in your client code—no manual typing needed
- Lesson 1565 — Type Inference Across Mutation Procedures
- TypeScript Blog
- and **@typescript** on social media keeps you informed about new releases and best practices as the language evolves.
- Lesson 39 — Community Resources and Learning
- TypeScript changes this
- The compiler needs to fully resolve types during compilation.
- Lesson 1630 — Circular Dependencies Breaking
- TypeScript compiler (`tsc`)
- Handles type extraction → `.
- Lesson 1246 — When Libraries Need Declaration Files Only
- TypeScript Compiler's `--noImplicitAny`
- Lesson 1678 — Auditing Codebases for any Usage
- TypeScript Discord
- and **Reddit's r/typescript** for quick questions
- Lesson 39 — Community Resources and Learning
- TypeScript ESLint Rules
- Lesson 1678 — Auditing Codebases for any Usage
- TypeScript Exercises
- , and **type-challenges** on GitHub offer progressively harder problems.
- Lesson 39 — Community Resources and Learning
- TypeScript immediately errors
- at `assertNever(shape)` because `shape` could now be a triangle, not `never`.
- Lesson 424 — Adding New Union Variants Safely
- TypeScript infers types
- from that schema automatically
- Lesson 1544 — Mutation Procedures with Input Types
- TypeScript Language Service
- Your editor's built-in "Add all missing imports" and quick-fix actions can auto-generate basic type stubs
- Lesson 1648 — Alternative Tools: dts-gen and Others
- TypeScript Playground
- – an in-browser editor where you can write TypeScript and instantly see the compiled JavaScript alongside type errors
- Lesson 39 — Community Resources and Learning
- TypeScript the language
- becomes less distinct from JavaScript
- Lesson 1786 — Long-Term Vision: Types in JavaScript
- TypeScript the tool
- becomes *more* essential as the de facto type checker
- Lesson 1786 — Long-Term Vision: Types in JavaScript
- TypeScript types
- compile-time types for your form data
- Lesson 1304 — Typed Form Validation with Inferred Schemas
- TypeScript's type system itself
- as the transport mechanism.
- Lesson 1314 — tRPC for Zero-Code-Gen Type Safety
- TypeStat
- Mentioned earlier, focuses on adding type annotations based on usage analysis
- Lesson 1648 — Alternative Tools: dts-gen and Others
- TypeWiz
- takes a different approach: it instruments your JavaScript code during development, observes actual values passed to functions as you run your application or tests, and then suggests type annotations based on observed usage.
- Lesson 1648 — Alternative Tools: dts-gen and Others
- Typical setup
- Lesson 1240 — Running tsc in Parallel with Bundling
- Typo protection evaporates
- Lesson 878 — Lost Autocomplete and IntelliSense
- Typos are caught
- Invalid keys produce errors immediately
- Lesson 317 — Index Signatures and Record Utility
U
- UMD modules
- that can be used both globally and as imports
- Lesson 1134 — Namespaces in Declaration Files
- Unchecked by default
- Files without the Flow comment are ignored entirely
- Lesson 23 — Flow: Facebook's Type Checker
- Under 50 files
- Manual migration is almost certainly faster and produces better results.
- Lesson 1649 — When Automation Helps vs Manual Migration
- Understanding paths mappings
- Is your `baseUrl` or `paths` configuration working?
- Lesson 1120 — Module Resolution Tracing with --traceResolution
- Undocumented
- Error messages become cryptic novels
- Lesson 652 — When Conditional Constraints Become Too Complex
- Unforgeable
- Unlike string literal brands, you cannot accidentally create matching structures.
- Lesson 1351 — Declaring Brand Symbols
- Unification
- is the mechanism for making two types "match" by finding substitutions for type parameters.
- Lesson 1702 — Constraint Solving and UnificationLesson 1707 — Contextual Typing PerformanceLesson 1717 — The Hidden Cost of Inference
- Unify types
- Find that `T = string` (widened from literal `"hello"`) and `U = number`
- Lesson 1702 — Constraint Solving and Unification
- union
- of two literal types: `true | false`.
- Lesson 460 — Boolean as Literal TypesLesson 800 — Union Collapse with Multiple infer SitesLesson 801 — Covariance and Contravariance with inferLesson 853 — Recursive Path Types for Deep ObjectsLesson 1444 — Covariance and Contravariance with inferLesson 1445 — Union Distribution Through infer
- Union and intersection operators
- `string | number`, `A & B`
- Lesson 1769 — Syntax That Would Be Standardized
- Union approach
- Lesson 778 — Readability vs Power Trade-offs
- Union everything together
- to create all possible paths
- Lesson 852 — Constructing Path Unions from Object Keys
- Union explosion
- A type that generates hundreds of union members slows down checking for every variable using that type
- Lesson 1472 — Limits of Type-Level Computation
- Union or intersection types
- combining multiple shapes
- Lesson 1735 — Prefer Type Aliases Over Complex Inline Types
- Union parameters
- are simpler—they say "this parameter can be type A OR type B.
- Lesson 278 — Overloads vs Union ParametersLesson 1665 — Unions Widen, Generics Narrow
- union type
- lets you say "this value can be Type A *or* Type B *or* Type C.
- Lesson 101 — Primitive Union TypesLesson 105 — Typed Array LiteralsLesson 173 — Contextual Union TypesLesson 183 — Return Type Inference with Multiple ReturnsLesson 321 — Alternatives to Index SignaturesLesson 382 — What Union Types AreLesson 769 — Conditional Types with Union Input
- union types
- (`string | number`) and alias them with `type`.
- Lesson 354 — Aliasing Intersection TypesLesson 387 — Unions vs Overloads
- Union with undefined
- (`age: number | undefined`) means "the key must be present, but can be `undefined`"
- Lesson 1205 — exactOptionalPropertyTypes: Optional vs Undefined
- Union/intersection operations
- (Exclude, Extract, NonNullable)
- Lesson 716 — The Full Standard Library Reference
- unions
- for covariant positions (like returns) and **intersections** for contravariant positions (like parameters).
- Lesson 800 — Union Collapse with Multiple infer SitesLesson 801 — Covariance and Contravariance with inferLesson 1670 — The Readability Trade-off
- Unions (`|`)
- make optional properties **more optional**
- Lesson 442 — Intersection vs Union for Optional Properties
- Unions combine multiple possibilities
- into a single type.
- Lesson 1661 — The Core Difference: Generics Preserve, Unions Combine
- Unmaintainable
- Small changes break everything in mysterious ways
- Lesson 652 — When Conditional Constraints Become Too Complex
- Unreadable
- Even you struggle to understand them a week later
- Lesson 652 — When Conditional Constraints Become Too Complex
- Unreadable error messages
- (hundreds of string literals)
- Lesson 1716 — String Template Literal Type Explosion
- Unrelated optionality
- where one field requires another
- Lesson 1346 — Refactoring Toward Impossible States
- Unresponsive editor
- typing feels laggy, especially in large files
- Lesson 1505 — IDE Performance Degradation
- Unteachable
- New team members avoid touching your code
- Lesson 652 — When Conditional Constraints Become Too Complex
- Untyped Libraries
- Lesson 1125 — When You Need Declaration Files
- Unwrapping nested promises
- Lesson 1439 — Nested infer for Deep Extraction
- Update operations
- You only want to change a few fields, not replace the whole object
- Lesson 664 — The Partial<T> Utility
- Update status checks
- with pass/fail and error count
- Lesson 1270 — Reporting Type Errors in Pull Requests
- URI Registry Pattern
- solves this by using string literal types as unique keys in a global interface.
- Lesson 1499 — The URI Registry Pattern
- URIs
- String literal types like `'Option'`, `'Either'`, `'Array'`
- Lesson 1502 — Libraries That Use HKT Simulation: fp-ts
- Usage example
- Lesson 1381 — Tuple Type Utilities: First and Last
- Usage examples would help
- callers understand the common patterns
- Lesson 1684 — JSDoc Comments for Public APIs
- Use @types
- when available — it's maintained by the community and kept up-to-date
- Lesson 1147 — Typing Third-Party Libraries
- Use `as const` when
- Lesson 473 — as const vs readonly Modifiers
- Use `excludeFiles` wisely
- Don't include test fixtures or build artifacts in your projects
- Lesson 1753 — Workspace Recommendations for Speed
- Use `import type` when
- Lesson 1109 — Type-Only Import Best Practices
- Use `mutation()` when
- Lesson 1566 — Idempotency and Query vs Mutation Choice
- Use `Partial<T>` when
- Lesson 673 — When to Use Each Utility
- Use `query()` when
- Lesson 1566 — Idempotency and Query vs Mutation Choice
- Use `ReactElement` when
- You need exactly one React component/element as a child.
- Lesson 1519 — Children Props and ReactNode
- Use `ReactNode` when
- You want maximum flexibility and don't care about the exact structure of children.
- Lesson 1519 — Children Props and ReactNode
- Use `readonly` when
- Lesson 473 — as const vs readonly Modifiers
- Use `Readonly<T>` when
- Lesson 673 — When to Use Each Utility
- Use `Required<T>` when
- Lesson 673 — When to Use Each Utility
- Use an arrow function
- (which captures `this` from the surrounding scope):
- Lesson 1186 — noImplicitThis
- Use anonymous types
- for one-off structures that appear only once, especially simple shapes or quick function parameters.
- Lesson 294 — Anonymous vs Named Object Types
- Use array parameters when
- Lesson 267 — Rest Parameters vs Array Parameters
- Use arrays when
- Lesson 1370 — Tuple Types vs Array Types
- Use arrow functions
- (which capture `this` from their surrounding context)
- Lesson 1217 — noImplicitThis: Preventing Untyped this
- Use broader constraints
- Lesson 1740 — Limit Generic Constraint Complexity
- Use case
- When you need to know what context object a function expects.
- Lesson 711 — ThisParameterType<T> and OmitThisParameter<T>
- Use community type definitions
- from DefinitelyTyped (`@types/*` packages)
- Lesson 884 — any in Third-Party Libraries
- Use declaration merging when
- Lesson 369 — When to Leverage Declaration Merging
- Use discriminated unions when
- Lesson 1653 — Discriminated Unions vs Flat String Unions
- Use generic unions when
- Lesson 1668 — Overloads vs Generic Union Parameters
- Use generics
- when the output type depends on the input type in a predictable way (like returning an array of whatever type you passed in)
- Lesson 550 — Generic Functions vs Function OverloadsLesson 1665 — Unions Widen, Generics Narrow
- Use intersections when
- Lesson 455 — Avoiding Intersection Overuse
- Use overloads
- when you need specific, unrelated type mappings for different cases (like a function that accepts a number and returns a string, or accepts a boolean and returns an array)
- Lesson 550 — Generic Functions vs Function Overloads
- Use overloads when
- Lesson 1668 — Overloads vs Generic Union Parameters
- Use rest parameters when
- Lesson 267 — Rest Parameters vs Array Parameters
- Use runtime validation
- where compile-time checking becomes too expensive
- Lesson 865 — Practical Limits of Path Type Complexity
- Use simpler patterns
- when possible—sometimes a mapped type beats recursive `infer`.
- Lesson 1448 — Performance Considerations with Complex infer
- Use smaller intersections
- Build complex intersections piece by piece to catch conflicts early.
- Lesson 448 — Deep Property Conflicts
- Use treeshaking-friendly validators
- Modern validators like Zod and ArkType are designed to treeshake unused schema definitions.
- Lesson 1297 — Performance and Bundle Size Considerations
- Use tuples when
- Lesson 1370 — Tuple Types vs Array Types
- Use type aliases
- at module boundaries to flatten complex unions
- Lesson 1482 — Library Boundaries and Type Complexity
- Use type tests
- Create explicit test types with known inputs to isolate which transformation step breaks.
- Lesson 1691 — Debugging Complex Generic Errors
- Use union return types
- or a broad return type that covers all cases
- Lesson 1409 — Implementation Signature Compatibility
- Use union types
- for parameters that vary across overloads
- Lesson 1409 — Implementation Signature Compatibility
- Use unions
- when your function genuinely needs to handle distinct cases differently and the output type depends on runtime logic.
- Lesson 1665 — Unions Widen, Generics Narrow
- User preferences by ID
- `{ "user123": true, "user456": false }` — user IDs are dynamic
- Lesson 310 — What Index Signatures Solve
- User-generated content
- You cannot predict what users will submit through form fields or file uploads.
- Lesson 1511 — Accept Some Dynamic Behavior with unknown
- Using simpler patterns
- when possible (Pick/Omit instead of custom remapping)
- Lesson 764 — Performance Considerations with as
- Utility functions
- they're used everywhere, so typing them helps everything else
- Lesson 1621 — Dealing with Implicit any in Legacy Code
V
- Validate
- Check that these solutions satisfy all constraints
- Lesson 1702 — Constraint Solving and Unification
- Validate each property
- with typeof or other guards
- Lesson 927 — Validating Object Shape with Type Predicates
- Validate the design
- by writing example usage (no implementation yet)
- Lesson 1327 — Designing Public APIs with Types
- Validated data
- `Email`, `PhoneNumber`, `URL` ensure format checks
- Lesson 1353 — Branding Primitive Types
- Validates your input
- matches the Zod schema you defined on the server
- Lesson 1565 — Type Inference Across Mutation Procedures
- Validation results
- where partial input becomes complete output
- Lesson 723 — Making All Properties Required
- Validation rules
- runtime checks to ensure data is correct
- Lesson 1304 — Typed Form Validation with Inferred Schemas
- value
- is the concrete data itself: `42`, `"hello"`, `true`.
- Lesson 93 — Literal Values vs Type NamesLesson 497 — Enum Member Name vs Value
- Variable declarations
- specifying what type something is
- Lesson 1138 — Basic Declaration File Structure
- Variables injected
- via a `<script>` tag before your code runs
- Lesson 1150 — What declare Does: Ambient Declarations
- Variables without initialization
- are another source: if you declare a variable without assigning a value or providing a type annotation, TypeScript has nothing to work with and defaults to `any`.
- Lesson 1672 — Implicit any from Missing Type Annotations
- Variadic tuple syntax
- lets you combine fixed tuple elements with variable-length segments using the spread operator (`.
- Lesson 1385 — Basic Variadic Tuple Syntax
- Variadic Tuples
- made it possible to work with tuple types more flexibly, especially when combining multiple tuples together—like having a more powerful way to describe function argument lists.
- Lesson 18 — TypeScript 4.x: Refinement and PerformanceLesson 1384 — What Are Variadic Tuples?Lesson 1394 — Variadic Tuples vs Rest Parameters
- Verbose syntax
- The comment format is clunky compared to TypeScript's inline types
- Lesson 26 — JSDoc Type Annotations in Plain JavaScript
- Verify with `--noEmit`
- to ensure type-checking still passes
- Lesson 1262 — Debugging Bundler Type Issues
- Via command line
- Lesson 82 — The --declaration Flag: Generating .d.ts Files
- Via tsconfig.json
- Lesson 82 — The --declaration Flag: Generating .d.ts Files
- Vim/Neovim
- Restart your LSP client (`:LspRestart` in many setups)
- Lesson 1752 — Restart Language Service When Stuck
- Visual Studio Code (2015)
- gave TypeScript an unexpected advantage.
- Lesson 20 — Community Adoption Milestones
- Visualize progress
- Add a progress bar to your README or CI dashboard
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- Vite
- , **esbuild**, and **swc** have TypeScript compilation built directly into their bundling process.
- Lesson 35 — Build Tools and TypeScriptLesson 72 — Using TypeScript with Bundlers (Webpack, Vite, Parcel)Lesson 73 — TypeScript in the Browser via Build ToolsLesson 1242 — Source Maps Across ToolsLesson 1258 — When to Enable isolatedModulesLesson 1792 — Ecosystem Integration: Bundlers and Runtimes
- Vitest
- , and **Playwright** all support TypeScript out of the box or with minimal configuration.
- Lesson 37 — Testing with TypeScript
W
- watch mode
- solves this by monitoring your source files for changes.
- Lesson 68 — Watching Files with tsc --watchLesson 76 — Understanding Compilation Modes: Build vs Watch vs Project
- Watches all source files
- across the entire project graph
- Lesson 1230 — Watch Mode with Project References
- We can do better
- Lesson 934 — Generic parseResponse Helper Function
- Webpack
- typically uses `ts-loader` (which calls `tsc` internally) or `babel-loader` with TypeScript presets
- Lesson 72 — Using TypeScript with Bundlers (Webpack, Vite, Parcel)Lesson 73 — TypeScript in the Browser via Build ToolsLesson 1234 — Bundlers: Webpack, Rollup, esbuild, and OthersLesson 1258 — When to Enable isolatedModules
- WebSocket/REST Requirements
- Teams with established REST conventions, OpenAPI tooling, or WebSocket needs may find tRPC's RPC model doesn't align with their architecture.
- Lesson 1559 — Trade-offs: When tRPC Fits vs Doesn't
- WebStorm/IntelliJ
- File → Invalidate Caches → Restart
- Lesson 1752 — Restart Language Service When Stuck
- Week 1-2
- Convert all utility modules (no dependencies on other files)
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- Week 3-4
- Convert API clients and data models
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- Week 5-8
- Convert React components, starting with leaf components
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- Week 9-12
- Convert route handlers and business logic
- Lesson 1619 — Tracking Progress and Setting Migration Goals
- What
- the expected future resolution is
- Lesson 899 — Acceptable Use Cases for SuppressionsLesson 1587 — Configuring GraphQL CodegenLesson 1659 — Naming Conventions for Focused Types
- What data shapes exist
- in your domain (interfaces, type aliases)
- Lesson 1322 — What Type-Driven Design Means
- What invariants must hold
- (constraints, readonly properties, branded types)
- Lesson 1322 — What Type-Driven Design Means
- What operations are allowed
- (function signatures with strict parameters)
- Lesson 1322 — What Type-Driven Design Means
- What states are possible
- (discriminated unions for state machines)
- Lesson 1322 — What Type-Driven Design Means
- What TypeScript eliminates
- Tests checking "Did I pass 3 arguments when the function expects 2?
- Lesson 9 — The Testing Tradeoff
- What you still need
- Tests verifying "Does my shopping cart calculate discounts correctly?
- Lesson 9 — The Testing Tradeoff
- What's the failure cost
- Financial transactions demand precision
- Lesson 1698 — Finding the Right Abstraction Level
- When to choose
- You're maintaining existing code using Yup, or your team already knows it well
- Lesson 1295 — Alternatives: Yup, io-ts, ArkType
- When to use global
- Great for quick experiments, learning, or using TypeScript's command-line tools (`tsc`) from anywhere.
- Lesson 41 — Installing TypeScript Globally vs Locally
- When to use local
- This is the **recommended approach** for real projects.
- Lesson 41 — Installing TypeScript Globally vs Locally
- Where the mismatch occurred
- (in nested or complex types)
- Lesson 650 — Error Messages from Failed Conditional Constraints
- Which constraint failed
- (the conditional check itself)
- Lesson 650 — Error Messages from Failed Conditional Constraints
- Which transitions are valid
- (enforced through discriminated unions)
- Lesson 595 — Generic State Machines
- Who maintains this
- Junior devs benefit from explicit types
- Lesson 1698 — Finding the Right Abstraction Level
- Why
- "No types available for legacy API"
- Lesson 875 — Documenting Known Type GapsLesson 899 — Acceptable Use Cases for Suppressions
- Why it failed
- (the type didn't match the expected shape)
- Lesson 650 — Error Messages from Failed Conditional Constraints
- Why it fails
- The bundler can't tell if `User` is a type or value without checking `types.
- Lesson 1262 — Debugging Bundler Type Issues
- Why it matters here
- You can't patch every consumer's codebase when they misuse your API.
- Lesson 1478 — When Type-Level Guarantees Matter Most
- Why this happens
- TypeScript's type system prioritizes flexibility.
- Lesson 119 — Tuple Length and Array Methods
- Why this matters
- It prevents callers from passing completely unrelated types when the logic requires them to be compatible.
- Lesson 627 — Constraining One Type Parameter to Another
- Wide Union Distributions
- Lesson 1631 — Build Times Exploding
- Widen the implementation signature
- Make it accept all possible parameter combinations using unions
- Lesson 1628 — Function Overload Conflicts
- widening
- TypeScript assumes you might reassign the variable later, so it gives you flexibility.
- Lesson 163 — Literals and Widening: When Inference HurtsLesson 177 — Array Literals Inferred as Mutable ArraysLesson 1665 — Unions Widen, Generics Narrow
- widens
- the type from the literal `"active"` to the primitive `string`.
- Lesson 98 — Primitive Type Widening on ReassignmentLesson 146 — Widening: From Literal to Broader TypesLesson 178 — Object Literals Widening to General TypesLesson 463 — Widening from Literals to PrimitivesLesson 467 — The Widening Problem Without as constLesson 1415 — Basic const Type Parameter SyntaxLesson 1416 — const vs Normal Type ParametersLesson 1701 — Widening: From Literal to General Types
- Wildcard module declarations
- let you tell TypeScript: "When someone imports a file matching this pattern (like `*.
- Lesson 1128 — Wildcard Module DeclarationsLesson 1155 — Wildcard Module Declarations
- With `const`
- Lesson 1421 — const Type Parameters in Classes
- With `isolatedModules: true`
- (used by Babel, esbuild, swc):
- Lesson 513 — The const Enum Escape Hatch Trade-offs
- With `unknown`
- TypeScript forces you to prove what type the value is before you use it.
- Lesson 940 — unknown vs any in Function Parameters
- With enums
- , TypeScript reports errors using the enum's name:
- Lesson 520 — Refactoring Safety and Autocomplete
- With regular arrays
- , TypeScript treats it as spreading an unknown number of elements
- Lesson 263 — Spread Operator in Function Calls
- With string-literal unions
- , TypeScript shows the actual values:
- Lesson 520 — Refactoring Safety and Autocomplete
- With tuples
- , each position maps directly to a parameter
- Lesson 263 — Spread Operator in Function Calls
- Without `const`
- Lesson 1421 — const Type Parameters in Classes
- Working Around Library Bugs
- Lesson 899 — Acceptable Use Cases for Suppressions
- Works with isolatedModules
- Build tools like Babel that compile files independently can safely strip type-only imports without analyzing the entire dependency graph.
- Lesson 1095 — Type-only import syntax with import type
- World-Class Tooling
- Lesson 28 — Why TypeScript Won Adoption
- Wrapped in a structure
- Treat the entire union as one type
- Lesson 779 — What Makes a Conditional Type Distributive
- Write the skeleton
- Create the function signature matching your type
- Lesson 1328 — Using Types to Drive Implementation
- Write your own
- for internal libraries, custom tools, or when @types doesn't exist
- Lesson 1147 — Typing Third-Party Libraries
- Wrong return type usage
- If you expect an object but the function returns an array, you'll know before deployment
- Lesson 8 — API Contract Enforcement
Y
- Years, not months
- Major TC39 proposals typically take 3-7 years from Stage 1 to Stage 4.
- Lesson 1776 — Timeline and Current Status
- Yes
- Recursively apply `DeepReadonly` to that nested object
- Lesson 813 — The DeepReadonly PatternLesson 1282 — When Type Assertions Are Acceptable
- You
- are responsible for the logic being correct.
- Lesson 398 — Type Predicates for Custom NarrowingLesson 1008 — Event Targets in Event Handlers
- You can read them
- No mystery about what `Partial<User>` does—it iterates over keys and adds `?
- Lesson 747 — Understanding How Built-in Utilities Work
- You gain
- Better type safety, more specific operations, clearer errors
- Lesson 632 — When Constraints Improve Safety vs Flexibility
- You lose
- Flexibility to use your generic with broader input types
- Lesson 632 — When Constraints Improve Safety vs Flexibility
- You maintain complexity
- that adds no business value
- Lesson 1510 — Use Libraries with Good Types Instead of Recreating Them
- You need constraints
- Type aliases with unions/intersections are more explicit and don't merge unexpectedly
- Lesson 369 — When to Leverage Declaration Merging
- You understand limitations
- Since they're shallow mappings, they don't transform nested objects
- Lesson 747 — Understanding How Built-in Utilities Work
- You'll hit edge cases
- you didn't anticipate (variance issues, inference failures, recursive depth limits)
- Lesson 1510 — Use Libraries with Good Types Instead of Recreating Them
- You're building library boundaries
- where callers shouldn't care about variants they don't use
- Lesson 1656 — When a Single Focused Type Is Better Than a Union
- You're building reusable infrastructure
- When you find yourself applying the same complex transformation repeatedly, extract it into a named custom mapped type for your codebase.
- Lesson 715 — When to Use vs Custom Mapped Types
- You're publishing a library
- where users expect full TypeScript support
- Lesson 1602 — When to Stop and ShipLesson 1684 — JSDoc Comments for Public APIs
- You're refactoring existing JavaScript
- Gradual migration benefits from incremental type addition
- Lesson 1326 — Type-First vs Code-First Trade-offs
- You're simulating higher-kinded types
- or building type-level parsers
- Lesson 1509 — Embrace Runtime Checks Over Type Gymnastics
- Your own compiled TypeScript
- can generate declaration files for consumers of your code
- Lesson 1124 — What Are Declaration Files (.d.ts)
- Yup
- predates Zod and was the go-to validation library for years, especially in React forms with Formik.
- Lesson 1295 — Alternatives: Yup, io-ts, ArkType
Z
- zero runtime cost
- no object lookup, no extra code.
- Lesson 501 — How const enums Are InlinedLesson 515 — Community Preference for UnionsLesson 893 — Performance and Runtime Impact
- zero runtime footprint
- perfect for keeping bundles small.
- Lesson 519 — Runtime Behavior DifferencesLesson 1351 — Declaring Brand Symbols
- Zod
- is a TypeScript-first schema validation library that lets you declare what your data *should* look like, then automatically validates it and provides full type safety—all in one step.
- Lesson 932 — Integrating Zod for unknown Validation
- zodios
- takes a different approach to type-safe REST.
- Lesson 1582 — zodios: OpenAPI-Style Type-Safe RESTLesson 1589 — When to Choose Each Approach