Skip to content

Commit

Permalink
fix #213: typeof must be followed by import type or entity name
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jul 2, 2020
1 parent 846d6b9 commit 2692cab
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

* Fix bug with TypeScript `typeof` operator ([#213](https://github.com/evanw/esbuild/issues/213))

The TypeScript parser in esbuild incorrectly treated `readonly` in `typeof readonly` as a type operator instead of an identifier, which meant that it expected a type expression to follow the `readonly` identifier. Type expressions containing `typeof readonly` are now parsed correctly.

## 0.5.18

* Fix bug with code splitting and side effects
Expand Down
19 changes: 17 additions & 2 deletions internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,9 +994,24 @@ func (p *parser) skipTypeScriptTypePrefix() {
}

case lexer.TTypeof:
// "typeof x"
p.lexer.Next()
p.skipTypeScriptType(ast.LPrefix)
if p.lexer.Token == lexer.TImport {
// "typeof import('fs')"
p.skipTypeScriptTypePrefix()
} else {
// "typeof x"
// "typeof x.y"
for {
if !p.lexer.IsIdentifierOrKeyword() {
p.lexer.Expected(lexer.TIdentifier)
}
p.lexer.Next()
if p.lexer.Token != lexer.TDot {
break
}
p.lexer.Next()
}
}

case lexer.TOpenBracket:
// "[number, string]"
Expand Down
7 changes: 7 additions & 0 deletions internal/parser/parser_ts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func TestTSTypes(t *testing.T) {
expectPrintedTS(t, "let x = [1] as readonly [number]", "let x = [1];\n")
expectPrintedTS(t, "let x = 'x' as keyof typeof Foo", "let x = \"x\";\n")
expectPrintedTS(t, "let fs: typeof import('fs') = require('fs')", "let fs = require(\"fs\");\n")
expectPrintedTS(t, "let fs: typeof import('fs').exists = require('fs').exists", "let fs = require(\"fs\").exists;\n")
expectPrintedTS(t, "let x: <T>() => Foo<T>", "let x;\n")
expectPrintedTS(t, "let x: new <T>() => Foo<T>", "let x;\n")
expectPrintedTS(t, "let x: <T extends object>() => Foo<T>", "let x;\n")
Expand All @@ -149,6 +150,12 @@ func TestTSTypes(t *testing.T) {
expectPrintedTS(t, "type Foo<T> = {-readonly [P in keyof T]: T[P]}", "")
expectPrintedTS(t, "type Foo<T> = {+readonly [P in keyof T]: T[P]}", "")
expectPrintedTS(t, "const x: unique symbol = y", "const x = y;\n")
expectPrintedTS(t, "let x: typeof a = y", "let x = y;\n")
expectPrintedTS(t, "let x: typeof a.b = y", "let x = y;\n")
expectPrintedTS(t, "let x: typeof a.if = y", "let x = y;\n")
expectPrintedTS(t, "let x: typeof if.a = y", "let x = y;\n")
expectPrintedTS(t, "let x: typeof readonly = y", "let x = y;\n")
expectParseErrorTS(t, "let x: typeof readonly Array", "<stdin>: error: Expected \";\" but found \"Array\"\n")
expectPrintedTS(t, "let x: `y`", "let x;\n")
expectParseErrorTS(t, "let x: tag`y`", "<stdin>: error: Expected \";\" but found \"`y`\"\n")

Expand Down

0 comments on commit 2692cab

Please sign in to comment.