Skip to content

TypeScript: variance annotations (<out A>, <in E>, <in out T>) are parse errors #3276

Open

Description

@inth3shadows

TypeScript 4.7 variance annotations on type parameters (<out A>, <in E>, <in out T>, <const in T>) are parse errors in the bundled TypeScript grammar, tree-sitter-typescript v0.23.2 (grammars.ts:386). That is upstream tree-sitter/tree-sitter-typescript#370, which is still open. The grammar repo has had no commit since 2025-01-30.

Repro (main f72c9d2e, bundled tree-sitter-typescript.wasm, web-tree-sitter 0.25.10)

source hasError tree
interface S<out A, in E> {} true (type_parameters (type_parameter name: …) (ERROR (identifier)) …)
function f<in out T>(x: T) {} true (type_parameters (type_parameter name: …) (ERROR (identifier) (identifier)))
class C<const in T> {} true (type_parameters (type_parameter name: …) (ERROR (identifier)))
interface S<A, E> {} (control) false

Expected: each parses clean, with the modifier attached to its type_parameter.

What it costs today

  • Error recovery is local in small files, so declarations in them are still extracted. Indexing packages/effect/src from Effect-TS/effect 7a87ff9 gives the same 31,478 nodes with and without a grammar that accepts the annotations.
  • The graph does lose edges. With the fixed grammar, the same index has 8 more references edges. For example, makeEquivalence in Redacted.ts:321 gains its references to Equivalence and Redacted, which sit after export interface Redacted<out A = string> (line 58).
  • Across the whole Effect repo, 239 of 2,054 files parse with an error; 185 still do once the annotations parse. The rest come from other grammar bugs, such as bug: anonymous generic call signatures fail to parse when separated only by line breaks tree-sitter/tree-sitter-typescript#335.

Libraries that use variance annotations heavily (Effect, and code that copies its patterns) are the ones affected.

A fix is up as #3226. It carries a patch for the grammar, following the existing docs/grammars/*.patch pattern.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions