Skip to content

Commit 147163e

Browse files
committed
#2380: allow declare class field initializers
1 parent a2789bf commit 147163e

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,33 @@
6060

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

63+
* Allow `declare` class fields to be initialized ([#2380](https://github.com/evanw/esbuild/issues/2380))
64+
65+
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:
66+
67+
```ts
68+
declare const enum a { b = 0 }
69+
70+
class Foo {
71+
// These are allowed by TypeScript
72+
declare readonly a = 0
73+
declare readonly b = -0
74+
declare readonly c = 0n
75+
declare readonly d = -0n
76+
declare readonly e = 'x'
77+
declare readonly f = `x`
78+
declare readonly g = a.b
79+
declare readonly h = a['b']
80+
81+
// These are not allowed by TypeScript
82+
declare readonly x = (0)
83+
declare readonly y = null
84+
declare readonly z = -a.b
85+
}
86+
```
87+
88+
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.
89+
6390
* Fix a bug in esbuild's feature compatibility table generator ([#2365](https://github.com/evanw/esbuild/issues/2365))
6491

6592
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/.

internal/js_parser/js_parser.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,10 +1984,6 @@ func (p *parser) parseProperty(startLoc logger.Loc, kind js_ast.PropertyKind, op
19841984
}
19851985

19861986
if p.lexer.Token == js_lexer.TEquals {
1987-
if opts.tsDeclareRange.Len != 0 {
1988-
p.log.AddError(&p.tracker, p.lexer.Range(), "Class fields that use \"declare\" cannot be initialized")
1989-
}
1990-
19911987
p.lexer.Next()
19921988

19931989
// "this" and "super" property access is allowed in field initializers

internal/js_parser/ts_parser_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ func TestTSClass(t *testing.T) {
510510
expectPrintedTS(t, "class Foo { override public foo: number }", "class Foo {\n}\n")
511511
expectPrintedTS(t, "class Foo { public override foo: number }", "class Foo {\n}\n")
512512
expectPrintedTS(t, "class Foo { declare override public foo: number }", "class Foo {\n}\n")
513-
expectParseErrorTS(t, "class Foo { declare foo = 123 }", "<stdin>: ERROR: Class fields that use \"declare\" cannot be initialized\n")
513+
expectPrintedTS(t, "class Foo { declare foo = 123 }", "class Foo {\n}\n")
514514

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

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

0 commit comments

Comments
 (0)