Advanced TypeScript Types for Better Code

TypeScript's type system goes far beyond basic interfaces and enums. Advanced types catch more bugs, reduce boilerplate, and document code more precisely.


Generics


Generics parameterize types. A generic function works with any type while maintaining type safety. Type parameters infer from usage—explicit annotation is often unnecessary. Constrain type parameters with extends to limit acceptable types.


Generic constraints with keyof access the keys of an object type. T[K] (indexed access) retrieves the type of property K in type T. This enables type-safe property access and transformation functions.


Conditional Types


Conditional types select types based on conditions: T extends U ? X : Y. They are TypeScript's equivalent of ternary expressions at the type level. Nested conditionals handle multiple branches.


The infer keyword extracts types from within other types. ReturnType uses infer to extract the return type of a function type. Template literal types with infer parse string patterns at the type level.


Mapped Types


Mapped types transform object types by mapping over keys: { [K in keyof T]: NewType }. Readonly, Partial, and Pick are built-in mapped types. Custom mapped types implement selective transformations.


Key remapping with as creates mapped types that rename keys. Filter keys with as and a conditional type. These patterns implement advanced utilities like Omit, Extract, and Exclude.


Template Literal Types


Template literal types construct string types at the type level: `${prefix}${suffix}`. They combine with union types to generate all possible string patterns. Use with infer to parse URL patterns, routes, and string-based protocols.


Practical Usage


Use branded types for type-safe IDs (type UserId = string & {__brand: 'UserId'}). Use discriminated unions with switch-case exhaustiveness checking. Use satisfies keyword for type validation without widening.


Utility Types


Learn built-in utility types: Partial, Required, Readonly, Record, Pick, Omit, Exclude, Extract, NonNullable, ReturnType, InstanceType, Parameters, Awaited. Combine them for complex type transformations without custom type definitions.