Skip to content

Commit

Permalink
#2380: allow declare class field initializers
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jul 10, 2022
1 parent a2789bf commit 147163e
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,33 @@

This fix was contributed by [@magic-akari](https://github.com/magic-akari).

* Allow `declare` class fields to be initialized ([#2380](https://github.com/evanw/esbuild/issues/2380))

This release fixes an oversight in the TypeScript parser that disallowed initializers for `declare` class fields. TypeScript actually allows the following limited initializer expressions for `readonly` fields:

```ts
declare const enum a { b = 0 }

class Foo {
// These are allowed by TypeScript
declare readonly a = 0
declare readonly b = -0
declare readonly c = 0n
declare readonly d = -0n
declare readonly e = 'x'
declare readonly f = `x`
declare readonly g = a.b
declare readonly h = a['b']

// These are not allowed by TypeScript
declare readonly x = (0)
declare readonly y = null
declare readonly z = -a.b
}
```

So with this release, esbuild now allows initializers for `declare` class fields too. To future-proof this in case TypeScript allows more expressions as initializers in the future (such as `null`), esbuild will allow any expression as an initializer and will leave the specifics of TypeScript's special-casing here to the TypeScript type checker.

* Fix a bug in esbuild's feature compatibility table generator ([#2365](https://github.com/evanw/esbuild/issues/2365))

Passing specific JavaScript engines to esbuild's `--target` flag restricts esbuild to only using JavaScript features that are supported on those engines in the output files that esbuild generates. The data for this feature is automatically derived from this compatibility table with a script: https://kangax.github.io/compat-table/.
Expand Down
4 changes: 0 additions & 4 deletions internal/js_parser/js_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1984,10 +1984,6 @@ func (p *parser) parseProperty(startLoc logger.Loc, kind js_ast.PropertyKind, op
}

if p.lexer.Token == js_lexer.TEquals {
if opts.tsDeclareRange.Len != 0 {
p.log.AddError(&p.tracker, p.lexer.Range(), "Class fields that use \"declare\" cannot be initialized")
}

p.lexer.Next()

// "this" and "super" property access is allowed in field initializers
Expand Down
6 changes: 3 additions & 3 deletions internal/js_parser/ts_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ func TestTSClass(t *testing.T) {
expectPrintedTS(t, "class Foo { override public foo: number }", "class Foo {\n}\n")
expectPrintedTS(t, "class Foo { public override foo: number }", "class Foo {\n}\n")
expectPrintedTS(t, "class Foo { declare override public foo: number }", "class Foo {\n}\n")
expectParseErrorTS(t, "class Foo { declare foo = 123 }", "<stdin>: ERROR: Class fields that use \"declare\" cannot be initialized\n")
expectPrintedTS(t, "class Foo { declare foo = 123 }", "class Foo {\n}\n")

expectPrintedTS(t, "class Foo { public static foo: number }", "class Foo {\n}\n")
expectPrintedTS(t, "class Foo { private static foo: number }", "class Foo {\n}\n")
Expand All @@ -524,8 +524,8 @@ func TestTSClass(t *testing.T) {
expectPrintedTS(t, "class Foo { public override static foo: number }", "class Foo {\n}\n")
expectPrintedTS(t, "class Foo { public static override foo: number }", "class Foo {\n}\n")
expectPrintedTS(t, "class Foo { declare override public static foo: number }", "class Foo {\n}\n")
expectParseErrorTS(t, "class Foo { declare static foo = 123 }", "<stdin>: ERROR: Class fields that use \"declare\" cannot be initialized\n")
expectParseErrorTS(t, "class Foo { static declare foo = 123 }", "<stdin>: ERROR: Class fields that use \"declare\" cannot be initialized\n")
expectPrintedTS(t, "class Foo { declare static foo = 123 }", "class Foo {\n}\n")
expectPrintedTS(t, "class Foo { static declare foo = 123 }", "class Foo {\n}\n")

expectParseErrorTS(t, "class Foo { declare #foo }", "<stdin>: ERROR: \"declare\" cannot be used with a private identifier\n")
expectParseErrorTS(t, "class Foo { declare [foo: string]: number }", "<stdin>: ERROR: \"declare\" cannot be used with an index signature\n")
Expand Down

0 comments on commit 147163e

Please sign in to comment.