Skip to content

Simplify type preservation: Use only Kit's global PreserveTypes interface #1416

@jasonkuhrt

Description

@jasonkuhrt

Simplify type preservation: Use only Kit's global PreserveTypes interface

Motivation

Currently, Graffle has a complex dynamic type preservation system that reads from context at type-check time:

  • $Context['typeHookRequestResultDataTypes'] - for extensions
  • $Context['scalars']['typesDecoded'] - for custom scalars

This context-reading approach is potentially slower than using TypeScript's global interface caching.

Proposal

Replace all dynamic preservation with Kit's static global KitLibrarySettings.Ts.PreserveTypes interface:

  1. Remove extensions hook: Delete typeHookRequestResultDataTypes from context

    • Extensions would declare their types in global PreserveTypes instead
  2. Remove .scalar() auto-preservation: Users of .scalar() API would need to manually augment global

    // User would need to add:
    declare global {
      namespace KitLibrarySettings {
        namespace Ts {
          interface PreserveTypes {
            _MyCustomDate: Date
          }
        }
      }
    }
  3. Generator emits global augmentation: Codegen automatically outputs PreserveTypes for custom scalars

    // Generated in global.ts:
    declare global {
      namespace KitLibrarySettings {
        namespace Ts {
          interface PreserveTypes {
            _Date: $$Scalar.DateDecoded
          }
        }
      }
    }
  4. Simplify RequestResult.Simplify: Just use Ts.Simplify.Deep<$Type> everywhere

    • No more context reading
    • Global types are cached by TypeScript (performance win)

Trade-offs

Benefits

  • Performance: Global types are instantiated once and cached by TS compiler
  • Simplicity: No more complex conditional logic in Simplify types
  • Consistency: One unified mechanism (global interface) for all preservation

Features Lost

  1. .scalar() API convenience: End users calling .scalar() must manually declare global

    • Impact: More manual work for non-generator users
    • Note: Generator users unaffected (codegen handles it automatically)
  2. Extension type parameters for preservation: Extensions can't use generic type parameters that flow into preservation

    • Example: An extension with <TCustomType> couldn't auto-preserve TCustomType
    • Impact: Likely minimal - this is a niche/advanced capability that may never be used
    • Workaround: Extensions can still document that users should augment global

Implementation Steps

  • Update src/types/RequestResult/Simplify.ts to use only Ts.Simplify.Deep
  • Remove typeHookRequestResultDataTypes from Context interface
  • Update src/generator/generators/global.ts to emit PreserveTypes augmentation
  • Update .scalar() API documentation to show manual global augmentation
  • Update extension documentation about PreserveTypes requirements
  • Remove context-based preservation tests
  • Add global-based preservation tests

Related

  • Part of performance optimization effort
  • Aligns with Kit's global settings pattern
  • Simplifies type system complexity

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions