Skip to content

Commit

Permalink
allow in and out with class expression params
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jan 27, 2023
1 parent 3c83a84 commit 71b3ef9
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 3 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## Unreleased

* Allow the `in` and `out` type parameter modifiers on class expressions

TypeScript 4.7 added the `in` and `out` modifiers on the type parameters of classes, interfaces, and type aliases. However, while TypeScript supported them on both class expressions and class statements, previously esbuild only supported them on class statements due to an oversight. This release now allows these modifiers on class expressions too:

```ts
declare let Foo: any;
Foo = class <in T> { };
Foo = class <out T> { };
```

## 0.17.4

* Implement HTTP `HEAD` requests in serve mode ([#2851](https://github.com/evanw/esbuild/issues/2851))
Expand Down
2 changes: 1 addition & 1 deletion internal/js_parser/js_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3428,7 +3428,7 @@ func (p *parser) parsePrefix(level js_ast.L, errors *deferredErrors, flags exprF

// Even anonymous classes can have TypeScript type parameters
if p.options.ts.Parse {
p.skipTypeScriptTypeParameters(typeParametersNormal)
p.skipTypeScriptTypeParameters(typeParametersWithInOutVarianceAnnotations)
}

class := p.parseClass(classKeyword, name, parseClassOpts{})
Expand Down
6 changes: 4 additions & 2 deletions internal/js_parser/ts_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,10 @@ func TestTSTypes(t *testing.T) {
expectParseErrorTS(t, "declare function foo<out T>()", "<stdin>: ERROR: The modifier \"out\" is not valid here:\n")
expectParseErrorTS(t, "declare let foo: Foo<in T>", "<stdin>: ERROR: Unexpected \"in\"\n")
expectParseErrorTS(t, "declare let foo: Foo<out T>", "<stdin>: ERROR: Expected \">\" but found \"T\"\n")
expectParseErrorTS(t, "Foo = class <in T> {}", "<stdin>: ERROR: The modifier \"in\" is not valid here:\n")
expectParseErrorTS(t, "Foo = class <out T> {}", "<stdin>: ERROR: The modifier \"out\" is not valid here:\n")
expectPrintedTS(t, "Foo = class <in T> {}", "Foo = class {\n};\n")
expectPrintedTS(t, "Foo = class <out T> {}", "Foo = class {\n};\n")
expectPrintedTS(t, "Foo = class Bar<in T> {}", "Foo = class Bar {\n};\n")
expectPrintedTS(t, "Foo = class Bar<out T> {}", "Foo = class Bar {\n};\n")
expectParseErrorTS(t, "foo = function <in T>() {}", "<stdin>: ERROR: The modifier \"in\" is not valid here:\n")
expectParseErrorTS(t, "foo = function <out T>() {}", "<stdin>: ERROR: The modifier \"out\" is not valid here:\n")
expectParseErrorTS(t, "class Foo { foo<in T>(): T {} }", "<stdin>: ERROR: The modifier \"in\" is not valid here:\n")
Expand Down

0 comments on commit 71b3ef9

Please sign in to comment.