Skip to content

Feature request: diagnostic message transformation hook in decorateProgram / LanguagePlugin? #304

Description

@johanrd

Not sure what the best approach here, so this is as much a question as a request:

Volar's decorateProgram correctly remaps diagnostic locations from generated code back to source via transformDiagnostic – but is there a hook for language plugins to transform diagnostic messages?

Language plugins that want to augment TS error messages with domain-specific guidance (e.g. augmenting a TS2345: Argument of type 'unknown' is not assignable to parameter of type 'Element' into a more helpful message like An Element must be specified in the component signature in order to use ...attributes) can do so in the tsserver-plugin (IDE) path — but currently not in the CLI (tsc) path?

In Glint we have an augmentDiagnostics function that rewrites certain TS errors into template-aware messages. When trying to get the same augmentation to the cli, it didn't feel right.

Possible API

A transformDiagnostic callback on the LanguagePlugin.typescript interface?

interface LanguagePlugin {                                                                                                                                       
  typescript?: {                                                  
    // ...existing properties...                                                                                                                                 
                                                                                                                                                                 
    /**                                                                                                                                                          
     * Called after Volar remaps a diagnostic's location back to source.                                                                                         
     * Allows the language plugin to rewrite the diagnostic message or                                                                                           
     * add additional context. Return undefined to filter the diagnostic.                                                                                        
     */                                                                                                                                                          
    transformDiagnostic?(diagnostic: ts.Diagnostic, virtualCode: VirtualCode): ts.Diagnostic | undefined;                                                        
  }                                                                                                                                                              
}                                                                                                                                                                

decorateProgram would then call this after transformDiagnostic remaps locations:

// in decorateProgram's getSemanticDiagnostics wrapper:                                                                                                          
return getSemanticDiagnostics(actualSourceFile, cancellationToken)
  .map(d => transformDiagnostic(language, d, program, true))
  .filter(d => !!d)
  .map(d => applyPluginTransform(language, d))  // <-- new step
  .filter(d => !!d);                                                                                                                                           

This could make diagnostic augmentation work consistently across both IDE and CLI paths

Use cases

  • Glint (Ember/Glimmer): rewriting TS errors about unknown element types into actionable guidance about component signatures
  • Any Volar-based language plugin that wants to provide domain-specific error messages on top of raw TS diagnostics
  • Potentially useful for Vue itself if there are ever Vue-specific error rewrites needed

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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