TypeScript Advanced Types
Parent: TypeScript Expert · researched 2026-06-03T23:22:42.205Z· 13 sources · 10 concepts · skill typescript-advanced-types
Expert reference for TypeScript's advanced type system. Covers conditional types, mapped types, branded/nominal types, type narrowing, generic constraints, variadic tuples, template literal types, uti
TypeScript Advanced Types
- Expert reference for TypeScript's advanced type system. Covers conditional types, mapped types, branded/nominal types, type narrowing, generic constraints, variadic tuples, template literal types, utility type internals, and type-level performance. [source]
When to use this skill
- Writing or reviewing generic type definitions, conditional types, or mapped types [source]
- Implementing branded/nominal types for domain safety [source]
- Debugging "Type instantiation is excessively deep" or union explosion errors [source]
- Designing type-safe builder patterns, event emitters, or state machines [source]
- Choosing between satisfies, type annotations, and type assertions [source]
- Optimizing slow type checking in large codebases [source]
When NOT to use this skill
Scope boundary
- This skill covers the TYPE SYSTEM exclusively. For general TypeScript project setup, runtime patterns, module resolution, or framework integration, use the typescript-expert skill instead. [source]
Distributive conditional types
The `infer` keyword
- Extract types from within structural positions: [source]
`infer` with constraints (TS 4.7+)
- Constrain the inferred type inline: [source]
Key remapping with `as` (TS 4.1+)
- Rename, prefix, or filter keys during iteration: [source]
Filtering keys with `as` + `never`
- Returning never from the as clause removes the key: [source]
Homomorphic mapped types
- A mapped type { [P in keyof T]: ... } is homomorphic -- it preserves the property modifiers (readonly, optional) of the source type T. This is what makes Readonly<T> and Partial<T> work correctly. [source]
- Key fact (a common myth, corrected): the compiler keys homomorphism on the in keyof T constraint, not on the presence of an as clause. Adding as does not by itself break homomorphism -- modifiers are still copied for every key that survives the remap. Only keys whose identity changes (e.g. remapped to a template-literal string) lose 1:1 modifier provenance, because the output key differs from the source key. So { [K in keyof T as F<K>]: ... } remains modifier-homomorphic over its surviving keys. [source]
3. Branded / Nominal Types
- TypeScript uses structural typing. Branded types simulate nominal typing by adding a phantom property that makes structurally identical types incompatible. [source]
Pattern 2: Unique symbol brand (library-safe)
- Unique symbols guarantee the brand key is truly unique, even across modules: [source]
Pattern 3: Flavor (weaker brand)
Assertion functions (TS 3.7+)
- Assertion functions narrow the type for all subsequent code in the same scope: [source]
The `satisfies` operator (TS 4.9+)
- satisfies validates a value against a type WITHOUT widening the inferred type: [source]
- When to use satisfies: [source]
- Config objects where you want validation + precise autocomplete [source]
- Discriminated union values where the discriminant literal must be preserved [source]
- as const objects that must conform to a schema [source]
`const` type parameters (TS 5.0+)
- Infer literal types by default instead of widened types: [source]
Constraint pattern: `readonly unknown[] | []`
- The [] in the union forces tuple inference for array literals instead of widening to arrays: [source]
Performance warning
- Template literal types create combinatorial unions. Interpolating two unions of size M and N produces M x N members. Keep interpolated unions under ~10 members each to avoid compiler slowdowns. [source]
`NoInfer<T>` (TS 5.4+)
- Blocks TypeScript from using a position for type inference: [source]
- Use cases for NoInfer: [source]
- Preventing default parameters from influencing generic inference [source]
- Ensuring one argument "drives" the generic while others are checked against it [source]
- API design where inference direction matters [source]
`Awaited<T>` (TS 4.5+)
- Recursively unwraps Promise types: [source]
Avoid deep instantiation
- Deeply nested generics are the primary cause of slow type checking. The compiler has hard limits: [source]
- Type instantiation depth: 50 levels (error: "Type instantiation is excessively deep and possibly infinite") [source]
- Type instantiation count: 5,000,000 total instantiations [source]
- Union constituent limit: 100,000 members [source]
Tail-call optimization for recursive types
- TypeScript recognizes tail-position recursive type aliases and can handle deeper recursion: [source]
Practical performance guidelines
- Flatten unions early. Large intermediate unions compound in later type operations. [source]
- Avoid Extract/Exclude on large unions in hot paths -- each distributes over every member. [source]
- Prefer interface over type for object shapes. Interfaces are cached by name; type aliases are structurally re-evaluated. [source]
- Use skipLibCheck: true to avoid type-checking node_modules .d.ts files in development. [source]
- Profile with --generateTrace. Run tsc --generateTrace traceDir and open the trace in chrome://tracing to find expensive types. [source]
- Keep template literal interpolations small. Two 10-member unions produce 100 variants; three produce 1,000. [source]
- Use interface extends over intersection & for combining object types -- intersections create anonymous types that are harder for the compiler to cache. [source]
Sources
- TypeScript Handbook: Conditional Types [source]
- TypeScript Handbook: Mapped Types [source]
- TypeScript Handbook: Template Literal Types [source]
- TypeScript Handbook: Narrowing [source]
- TypeScript Handbook: Utility Types [source]
- NoInfer: TypeScript 5.4's New Utility Type -- Total TypeScript [source]
- Branded Types in TypeScript -- shramko.dev [source]
- What the heck is a homomorphic mapped type? -- Andrea Simone Costa [source]
- Template literal types in TypeScript -- 2ality [source]
- Computing with tuple types in TypeScript -- 2ality [source]
- Conditional types in TypeScript -- 2ality [source]
- TypeScript Performance Optimization 2026 -- DEV Community [source]
Children
- No children recorded.