Skip to content

feat: support variance annotations on type parameters (TypeScript 4.7)#361

Draft
marionebl wants to merge 1 commit intotree-sitter:masterfrom
marionebl:feat/variance-type-parameters
Draft

feat: support variance annotations on type parameters (TypeScript 4.7)#361
marionebl wants to merge 1 commit intotree-sitter:masterfrom
marionebl:feat/variance-type-parameters

Conversation

@marionebl
Copy link
Copy Markdown

Summary

TypeScript 4.7 introduced in/out variance annotations on generic type parameters to explicitly declare variance:

interface Covariant<out T> {}       // covariant
interface Contravariant<in T> {}    // contravariant
interface Invariant<in out T> {}    // explicitly invariant

These were previously parsed as ERROR nodes. In effect-ts for example, 316 out of 1 767 .ts files contain variance annotations, producing 3 160 parse errors.

Changes

common/define-grammar.js

  • New named variance rule (modelled after override_modifier):
    variance: _ => choice(seq('in', 'out'), 'in', 'out'),
  • type_parameter gains optional($.variance) between the existing optional('const') and field('name', …).

Using a named node (rather than inline anonymous tokens) makes the annotation queryable via tree-sitter node queries.

test/corpus/types.txt — two new corpus test cases:

  • Variance annotations — all three forms + multiple params in a type alias
  • Variance annotations with constraints and defaults — real-world patterns from effect-ts

Test results

113 tests: 113 passed, 0 failed

Reference

TypeScript 4.7 introduced `in`/`out` variance annotations on type
parameters to explicitly declare covariance and contravariance:

    interface Covariant<out T> {}    // out → covariant
    interface Contravariant<in T> {} // in  → contravariant
    interface Invariant<in out T> {} // in out → invariant

Add a new named `variance` node and make it optional at the start of
`type_parameter`, consistent with the existing optional `const`
modifier for const type parameters (TypeScript 5.0).

Variance can be combined with constraints and defaults:

    interface Queue<out A, out R = never> {}
    type Covariant<out T extends string> = T;

Add two corpus test cases in `test/corpus/types.txt`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant