From 3ccec4b116bd78bd56b96ff400daab5db309302d Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Sat, 20 Apr 2019 01:45:01 +0300 Subject: [PATCH 01/10] Support template literals in enum declarations --- src/compiler/checker.ts | 8 +- ...stantMemberWithTemplateLiterals.errors.txt | 59 +++++++ .../enumConstantMemberWithTemplateLiterals.js | 85 ++++++++++ ...ConstantMemberWithTemplateLiterals.symbols | 102 ++++++++++++ ...umConstantMemberWithTemplateLiterals.types | 152 ++++++++++++++++++ ...mberWithTemplateLiteralsEmitDeclaration.js | 113 +++++++++++++ ...ithTemplateLiteralsEmitDeclaration.symbols | 88 ++++++++++ ...rWithTemplateLiteralsEmitDeclaration.types | 129 +++++++++++++++ .../enumConstantMemberWithTemplateLiterals.ts | 43 +++++ ...mberWithTemplateLiteralsEmitDeclaration.ts | 40 +++++ 10 files changed, 816 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/enumConstantMemberWithTemplateLiterals.errors.txt create mode 100644 tests/baselines/reference/enumConstantMemberWithTemplateLiterals.js create mode 100644 tests/baselines/reference/enumConstantMemberWithTemplateLiterals.symbols create mode 100644 tests/baselines/reference/enumConstantMemberWithTemplateLiterals.types create mode 100644 tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.js create mode 100644 tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.symbols create mode 100644 tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.types create mode 100644 tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts create mode 100644 tests/cases/conformance/enums/enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bf83f697d7ffa..9ac58c9d7f23b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6584,7 +6584,7 @@ namespace ts { } function isStringConcatExpression(expr: Node): boolean { - if (expr.kind === SyntaxKind.StringLiteral) { + if (isStringLiteralLike(expr)) { return true; } else if (expr.kind === SyntaxKind.BinaryExpression) { @@ -6601,6 +6601,7 @@ namespace ts { switch (expr.kind) { case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: return true; case SyntaxKind.PrefixUnaryExpression: return (expr).operator === SyntaxKind.MinusToken && @@ -6623,7 +6624,7 @@ namespace ts { for (const declaration of symbol.declarations) { if (declaration.kind === SyntaxKind.EnumDeclaration) { for (const member of (declaration).members) { - if (member.initializer && member.initializer.kind === SyntaxKind.StringLiteral) { + if (member.initializer && isStringLiteralLike(member.initializer)) { return links.enumKind = EnumKind.Literal; } if (!isLiteralEnumMember(member)) { @@ -30095,7 +30096,8 @@ namespace ts { } break; case SyntaxKind.StringLiteral: - return (expr).text; + case SyntaxKind.NoSubstitutionTemplateLiteral: + return (expr).text; case SyntaxKind.NumericLiteral: checkGrammarNumericLiteral(expr); return +(expr).text; diff --git a/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.errors.txt b/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.errors.txt new file mode 100644 index 0000000000000..e07f2ae26e0e0 --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.errors.txt @@ -0,0 +1,59 @@ +tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts(28,9): error TS2553: Computed values are not permitted in an enum with string valued members. +tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts(29,9): error TS2553: Computed values are not permitted in an enum with string valued members. +tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts(30,9): error TS2553: Computed values are not permitted in an enum with string valued members. +tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts(31,9): error TS2553: Computed values are not permitted in an enum with string valued members. + + +==== tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts (4 errors) ==== + enum T1 { + a = `1` + } + + enum T2 { + a = `1`, + b = "2", + c = 3 + } + + enum T3 { + a = `1` + `1` + } + + enum T4 { + a = `1`, + b = `1` + `1`, + c = `1` + "2", + d = "2" + `1`, + e = "2" + `1` + `1` + } + + enum T5 { + a = `1`, + b = `1` + `2`, + c = `1` + `2` + `3`, + d = 1, + e = `1` - `1`, + ~~~~~~~~~ +!!! error TS2553: Computed values are not permitted in an enum with string valued members. + f = `1` + 1, + ~~~~~~~ +!!! error TS2553: Computed values are not permitted in an enum with string valued members. + g = `1${"2"}3`, + ~~~~~~~~~~ +!!! error TS2553: Computed values are not permitted in an enum with string valued members. + h = `1`.length + ~~~~~~~~~~ +!!! error TS2553: Computed values are not permitted in an enum with string valued members. + } + + enum T6 { + a = 1, + b = `12`.length + } + + declare enum T7 { + a = `1`, + b = `1` + `1`, + c = "2" + `1` + } + \ No newline at end of file diff --git a/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.js b/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.js new file mode 100644 index 0000000000000..ebce0721df9f1 --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.js @@ -0,0 +1,85 @@ +//// [enumConstantMemberWithTemplateLiterals.ts] +enum T1 { + a = `1` +} + +enum T2 { + a = `1`, + b = "2", + c = 3 +} + +enum T3 { + a = `1` + `1` +} + +enum T4 { + a = `1`, + b = `1` + `1`, + c = `1` + "2", + d = "2" + `1`, + e = "2" + `1` + `1` +} + +enum T5 { + a = `1`, + b = `1` + `2`, + c = `1` + `2` + `3`, + d = 1, + e = `1` - `1`, + f = `1` + 1, + g = `1${"2"}3`, + h = `1`.length +} + +enum T6 { + a = 1, + b = `12`.length +} + +declare enum T7 { + a = `1`, + b = `1` + `1`, + c = "2" + `1` +} + + +//// [enumConstantMemberWithTemplateLiterals.js] +var T1; +(function (T1) { + T1["a"] = "1"; +})(T1 || (T1 = {})); +var T2; +(function (T2) { + T2["a"] = "1"; + T2["b"] = "2"; + T2[T2["c"] = 3] = "c"; +})(T2 || (T2 = {})); +var T3; +(function (T3) { + T3["a"] = "11"; +})(T3 || (T3 = {})); +var T4; +(function (T4) { + T4["a"] = "1"; + T4["b"] = "11"; + T4["c"] = "12"; + T4["d"] = "21"; + T4["e"] = "211"; +})(T4 || (T4 = {})); +var T5; +(function (T5) { + T5["a"] = "1"; + T5["b"] = "12"; + T5["c"] = "123"; + T5[T5["d"] = 1] = "d"; + T5[T5["e"] = 0] = "e"; + T5[T5["f"] = 0] = "f"; + T5[T5["g"] = 0] = "g"; + T5[T5["h"] = 0] = "h"; +})(T5 || (T5 = {})); +var T6; +(function (T6) { + T6[T6["a"] = 1] = "a"; + T6[T6["b"] = "12".length] = "b"; +})(T6 || (T6 = {})); diff --git a/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.symbols b/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.symbols new file mode 100644 index 0000000000000..ca16707dcb64d --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.symbols @@ -0,0 +1,102 @@ +=== tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts === +enum T1 { +>T1 : Symbol(T1, Decl(enumConstantMemberWithTemplateLiterals.ts, 0, 0)) + + a = `1` +>a : Symbol(T1.a, Decl(enumConstantMemberWithTemplateLiterals.ts, 0, 9)) +} + +enum T2 { +>T2 : Symbol(T2, Decl(enumConstantMemberWithTemplateLiterals.ts, 2, 1)) + + a = `1`, +>a : Symbol(T2.a, Decl(enumConstantMemberWithTemplateLiterals.ts, 4, 9)) + + b = "2", +>b : Symbol(T2.b, Decl(enumConstantMemberWithTemplateLiterals.ts, 5, 12)) + + c = 3 +>c : Symbol(T2.c, Decl(enumConstantMemberWithTemplateLiterals.ts, 6, 12)) +} + +enum T3 { +>T3 : Symbol(T3, Decl(enumConstantMemberWithTemplateLiterals.ts, 8, 1)) + + a = `1` + `1` +>a : Symbol(T3.a, Decl(enumConstantMemberWithTemplateLiterals.ts, 10, 9)) +} + +enum T4 { +>T4 : Symbol(T4, Decl(enumConstantMemberWithTemplateLiterals.ts, 12, 1)) + + a = `1`, +>a : Symbol(T4.a, Decl(enumConstantMemberWithTemplateLiterals.ts, 14, 9)) + + b = `1` + `1`, +>b : Symbol(T4.b, Decl(enumConstantMemberWithTemplateLiterals.ts, 15, 12)) + + c = `1` + "2", +>c : Symbol(T4.c, Decl(enumConstantMemberWithTemplateLiterals.ts, 16, 18)) + + d = "2" + `1`, +>d : Symbol(T4.d, Decl(enumConstantMemberWithTemplateLiterals.ts, 17, 18)) + + e = "2" + `1` + `1` +>e : Symbol(T4.e, Decl(enumConstantMemberWithTemplateLiterals.ts, 18, 18)) +} + +enum T5 { +>T5 : Symbol(T5, Decl(enumConstantMemberWithTemplateLiterals.ts, 20, 1)) + + a = `1`, +>a : Symbol(T5.a, Decl(enumConstantMemberWithTemplateLiterals.ts, 22, 9)) + + b = `1` + `2`, +>b : Symbol(T5.b, Decl(enumConstantMemberWithTemplateLiterals.ts, 23, 12)) + + c = `1` + `2` + `3`, +>c : Symbol(T5.c, Decl(enumConstantMemberWithTemplateLiterals.ts, 24, 18)) + + d = 1, +>d : Symbol(T5.d, Decl(enumConstantMemberWithTemplateLiterals.ts, 25, 24)) + + e = `1` - `1`, +>e : Symbol(T5.e, Decl(enumConstantMemberWithTemplateLiterals.ts, 26, 10)) + + f = `1` + 1, +>f : Symbol(T5.f, Decl(enumConstantMemberWithTemplateLiterals.ts, 27, 18)) + + g = `1${"2"}3`, +>g : Symbol(T5.g, Decl(enumConstantMemberWithTemplateLiterals.ts, 28, 16)) + + h = `1`.length +>h : Symbol(T5.h, Decl(enumConstantMemberWithTemplateLiterals.ts, 29, 19)) +>`1`.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +} + +enum T6 { +>T6 : Symbol(T6, Decl(enumConstantMemberWithTemplateLiterals.ts, 31, 1)) + + a = 1, +>a : Symbol(T6.a, Decl(enumConstantMemberWithTemplateLiterals.ts, 33, 9)) + + b = `12`.length +>b : Symbol(T6.b, Decl(enumConstantMemberWithTemplateLiterals.ts, 34, 10)) +>`12`.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +} + +declare enum T7 { +>T7 : Symbol(T7, Decl(enumConstantMemberWithTemplateLiterals.ts, 36, 1)) + + a = `1`, +>a : Symbol(T7.a, Decl(enumConstantMemberWithTemplateLiterals.ts, 38, 17)) + + b = `1` + `1`, +>b : Symbol(T7.b, Decl(enumConstantMemberWithTemplateLiterals.ts, 39, 12)) + + c = "2" + `1` +>c : Symbol(T7.c, Decl(enumConstantMemberWithTemplateLiterals.ts, 40, 18)) +} + diff --git a/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.types b/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.types new file mode 100644 index 0000000000000..b750b8e8ab444 --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithTemplateLiterals.types @@ -0,0 +1,152 @@ +=== tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts === +enum T1 { +>T1 : T1 + + a = `1` +>a : T1.a +>`1` : "1" +} + +enum T2 { +>T2 : T2 + + a = `1`, +>a : T2.a +>`1` : "1" + + b = "2", +>b : T2.b +>"2" : "2" + + c = 3 +>c : T2.c +>3 : 3 +} + +enum T3 { +>T3 : T3 + + a = `1` + `1` +>a : T3.a +>`1` + `1` : string +>`1` : "1" +>`1` : "1" +} + +enum T4 { +>T4 : T4 + + a = `1`, +>a : T4.a +>`1` : "1" + + b = `1` + `1`, +>b : T4.b +>`1` + `1` : string +>`1` : "1" +>`1` : "1" + + c = `1` + "2", +>c : T4.c +>`1` + "2" : string +>`1` : "1" +>"2" : "2" + + d = "2" + `1`, +>d : T4.d +>"2" + `1` : string +>"2" : "2" +>`1` : "1" + + e = "2" + `1` + `1` +>e : T4.e +>"2" + `1` + `1` : string +>"2" + `1` : string +>"2" : "2" +>`1` : "1" +>`1` : "1" +} + +enum T5 { +>T5 : T5 + + a = `1`, +>a : T5.a +>`1` : "1" + + b = `1` + `2`, +>b : T5.b +>`1` + `2` : string +>`1` : "1" +>`2` : "2" + + c = `1` + `2` + `3`, +>c : T5.c +>`1` + `2` + `3` : string +>`1` + `2` : string +>`1` : "1" +>`2` : "2" +>`3` : "3" + + d = 1, +>d : T5.d +>1 : 1 + + e = `1` - `1`, +>e : T5.e +>`1` - `1` : number +>`1` : "1" +>`1` : "1" + + f = `1` + 1, +>f : T5.e +>`1` + 1 : string +>`1` : "1" +>1 : 1 + + g = `1${"2"}3`, +>g : T5.e +>`1${"2"}3` : string +>"2" : "2" + + h = `1`.length +>h : T5.e +>`1`.length : number +>`1` : "1" +>length : number +} + +enum T6 { +>T6 : T6 + + a = 1, +>a : T6 +>1 : 1 + + b = `12`.length +>b : T6 +>`12`.length : number +>`12` : "12" +>length : number +} + +declare enum T7 { +>T7 : T7 + + a = `1`, +>a : T7.a +>`1` : "1" + + b = `1` + `1`, +>b : T7.b +>`1` + `1` : string +>`1` : "1" +>`1` : "1" + + c = "2" + `1` +>c : T7.c +>"2" + `1` : string +>"2" : "2" +>`1` : "1" +} + diff --git a/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.js b/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.js new file mode 100644 index 0000000000000..64e93dd62318f --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.js @@ -0,0 +1,113 @@ +//// [enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts] +enum T1 { + a = `1` +} + +enum T2 { + a = `1`, + b = "2", + c = 3 +} + +enum T3 { + a = `1` + `1` +} + +enum T4 { + a = `1`, + b = `1` + `1`, + c = `1` + "2", + d = "2" + `1`, + e = "2" + `1` + `1` +} + +enum T5 { + a = `1`, + b = `1` + `2`, + c = `1` + `2` + `3`, + d = 1 +} + +enum T6 { + a = 1, + b = `12`.length +} + +declare enum T7 { + a = `1`, + b = `1` + `1`, + c = "2" + `1` +} + + +//// [enumConstantMemberWithTemplateLiteralsEmitDeclaration.js] +var T1; +(function (T1) { + T1["a"] = "1"; +})(T1 || (T1 = {})); +var T2; +(function (T2) { + T2["a"] = "1"; + T2["b"] = "2"; + T2[T2["c"] = 3] = "c"; +})(T2 || (T2 = {})); +var T3; +(function (T3) { + T3["a"] = "11"; +})(T3 || (T3 = {})); +var T4; +(function (T4) { + T4["a"] = "1"; + T4["b"] = "11"; + T4["c"] = "12"; + T4["d"] = "21"; + T4["e"] = "211"; +})(T4 || (T4 = {})); +var T5; +(function (T5) { + T5["a"] = "1"; + T5["b"] = "12"; + T5["c"] = "123"; + T5[T5["d"] = 1] = "d"; +})(T5 || (T5 = {})); +var T6; +(function (T6) { + T6[T6["a"] = 1] = "a"; + T6[T6["b"] = "12".length] = "b"; +})(T6 || (T6 = {})); + + +//// [enumConstantMemberWithTemplateLiteralsEmitDeclaration.d.ts] +declare enum T1 { + a = "1" +} +declare enum T2 { + a = "1", + b = "2", + c = 3 +} +declare enum T3 { + a = "11" +} +declare enum T4 { + a = "1", + b = "11", + c = "12", + d = "21", + e = "211" +} +declare enum T5 { + a = "1", + b = "12", + c = "123", + d = 1 +} +declare enum T6 { + a = 1, + b +} +declare enum T7 { + a = "1", + b = "11", + c = "21" +} diff --git a/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.symbols b/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.symbols new file mode 100644 index 0000000000000..c1a8f52f005ad --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.symbols @@ -0,0 +1,88 @@ +=== tests/cases/conformance/enums/enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts === +enum T1 { +>T1 : Symbol(T1, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 0, 0)) + + a = `1` +>a : Symbol(T1.a, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 0, 9)) +} + +enum T2 { +>T2 : Symbol(T2, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 2, 1)) + + a = `1`, +>a : Symbol(T2.a, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 4, 9)) + + b = "2", +>b : Symbol(T2.b, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 5, 12)) + + c = 3 +>c : Symbol(T2.c, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 6, 12)) +} + +enum T3 { +>T3 : Symbol(T3, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 8, 1)) + + a = `1` + `1` +>a : Symbol(T3.a, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 10, 9)) +} + +enum T4 { +>T4 : Symbol(T4, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 12, 1)) + + a = `1`, +>a : Symbol(T4.a, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 14, 9)) + + b = `1` + `1`, +>b : Symbol(T4.b, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 15, 12)) + + c = `1` + "2", +>c : Symbol(T4.c, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 16, 18)) + + d = "2" + `1`, +>d : Symbol(T4.d, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 17, 18)) + + e = "2" + `1` + `1` +>e : Symbol(T4.e, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 18, 18)) +} + +enum T5 { +>T5 : Symbol(T5, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 20, 1)) + + a = `1`, +>a : Symbol(T5.a, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 22, 9)) + + b = `1` + `2`, +>b : Symbol(T5.b, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 23, 12)) + + c = `1` + `2` + `3`, +>c : Symbol(T5.c, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 24, 18)) + + d = 1 +>d : Symbol(T5.d, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 25, 24)) +} + +enum T6 { +>T6 : Symbol(T6, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 27, 1)) + + a = 1, +>a : Symbol(T6.a, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 29, 9)) + + b = `12`.length +>b : Symbol(T6.b, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 30, 10)) +>`12`.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +} + +declare enum T7 { +>T7 : Symbol(T7, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 32, 1)) + + a = `1`, +>a : Symbol(T7.a, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 34, 17)) + + b = `1` + `1`, +>b : Symbol(T7.b, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 35, 12)) + + c = "2" + `1` +>c : Symbol(T7.c, Decl(enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts, 36, 18)) +} + diff --git a/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.types b/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.types new file mode 100644 index 0000000000000..78111d51aff6e --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithTemplateLiteralsEmitDeclaration.types @@ -0,0 +1,129 @@ +=== tests/cases/conformance/enums/enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts === +enum T1 { +>T1 : T1 + + a = `1` +>a : T1.a +>`1` : "1" +} + +enum T2 { +>T2 : T2 + + a = `1`, +>a : T2.a +>`1` : "1" + + b = "2", +>b : T2.b +>"2" : "2" + + c = 3 +>c : T2.c +>3 : 3 +} + +enum T3 { +>T3 : T3 + + a = `1` + `1` +>a : T3.a +>`1` + `1` : string +>`1` : "1" +>`1` : "1" +} + +enum T4 { +>T4 : T4 + + a = `1`, +>a : T4.a +>`1` : "1" + + b = `1` + `1`, +>b : T4.b +>`1` + `1` : string +>`1` : "1" +>`1` : "1" + + c = `1` + "2", +>c : T4.c +>`1` + "2" : string +>`1` : "1" +>"2" : "2" + + d = "2" + `1`, +>d : T4.d +>"2" + `1` : string +>"2" : "2" +>`1` : "1" + + e = "2" + `1` + `1` +>e : T4.e +>"2" + `1` + `1` : string +>"2" + `1` : string +>"2" : "2" +>`1` : "1" +>`1` : "1" +} + +enum T5 { +>T5 : T5 + + a = `1`, +>a : T5.a +>`1` : "1" + + b = `1` + `2`, +>b : T5.b +>`1` + `2` : string +>`1` : "1" +>`2` : "2" + + c = `1` + `2` + `3`, +>c : T5.c +>`1` + `2` + `3` : string +>`1` + `2` : string +>`1` : "1" +>`2` : "2" +>`3` : "3" + + d = 1 +>d : T5.d +>1 : 1 +} + +enum T6 { +>T6 : T6 + + a = 1, +>a : T6 +>1 : 1 + + b = `12`.length +>b : T6 +>`12`.length : number +>`12` : "12" +>length : number +} + +declare enum T7 { +>T7 : T7 + + a = `1`, +>a : T7.a +>`1` : "1" + + b = `1` + `1`, +>b : T7.b +>`1` + `1` : string +>`1` : "1" +>`1` : "1" + + c = "2" + `1` +>c : T7.c +>"2" + `1` : string +>"2" : "2" +>`1` : "1" +} + diff --git a/tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts b/tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts new file mode 100644 index 0000000000000..f76cf3f20f7d9 --- /dev/null +++ b/tests/cases/conformance/enums/enumConstantMemberWithTemplateLiterals.ts @@ -0,0 +1,43 @@ +enum T1 { + a = `1` +} + +enum T2 { + a = `1`, + b = "2", + c = 3 +} + +enum T3 { + a = `1` + `1` +} + +enum T4 { + a = `1`, + b = `1` + `1`, + c = `1` + "2", + d = "2" + `1`, + e = "2" + `1` + `1` +} + +enum T5 { + a = `1`, + b = `1` + `2`, + c = `1` + `2` + `3`, + d = 1, + e = `1` - `1`, + f = `1` + 1, + g = `1${"2"}3`, + h = `1`.length +} + +enum T6 { + a = 1, + b = `12`.length +} + +declare enum T7 { + a = `1`, + b = `1` + `1`, + c = "2" + `1` +} diff --git a/tests/cases/conformance/enums/enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts b/tests/cases/conformance/enums/enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts new file mode 100644 index 0000000000000..ddd4e3e3d826f --- /dev/null +++ b/tests/cases/conformance/enums/enumConstantMemberWithTemplateLiteralsEmitDeclaration.ts @@ -0,0 +1,40 @@ +// @declaration: true +enum T1 { + a = `1` +} + +enum T2 { + a = `1`, + b = "2", + c = 3 +} + +enum T3 { + a = `1` + `1` +} + +enum T4 { + a = `1`, + b = `1` + `1`, + c = `1` + "2", + d = "2" + `1`, + e = "2" + `1` + `1` +} + +enum T5 { + a = `1`, + b = `1` + `2`, + c = `1` + `2` + `3`, + d = 1 +} + +enum T6 { + a = 1, + b = `12`.length +} + +declare enum T7 { + a = `1`, + b = `1` + `1`, + c = "2" + `1` +} From cbc5d2d5fe3dd0936a6bb566b0204a80fc853857 Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Thu, 25 Jul 2019 23:30:49 +0300 Subject: [PATCH 02/10] Support template literals in const enum access --- src/compiler/checker.ts | 4 +- src/compiler/transformers/ts.ts | 7 +- .../reference/constEnumErrors.errors.txt | 18 +- tests/baselines/reference/constEnumErrors.js | 4 +- .../reference/constEnumErrors.symbols | 55 ++-- .../baselines/reference/constEnumErrors.types | 9 +- .../constEnumSyntheticNodesComments.js | 36 ++ .../constEnumSyntheticNodesComments.symbols | 60 ++++ .../constEnumSyntheticNodesComments.types | 64 ++++ tests/baselines/reference/constEnums.js | 6 +- tests/baselines/reference/constEnums.symbols | 307 +++++++++--------- tests/baselines/reference/constEnums.types | 26 +- tests/cases/compiler/constEnumErrors.ts | 3 +- .../constEnumSyntheticNodesComments.ts | 18 + tests/cases/compiler/constEnums.ts | 4 +- 15 files changed, 429 insertions(+), 192 deletions(-) create mode 100644 tests/baselines/reference/constEnumSyntheticNodesComments.js create mode 100644 tests/baselines/reference/constEnumSyntheticNodesComments.symbols create mode 100644 tests/baselines/reference/constEnumSyntheticNodesComments.types create mode 100644 tests/cases/compiler/constEnumSyntheticNodesComments.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9ac58c9d7f23b..abfe768bc3c52 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21467,7 +21467,7 @@ namespace ts { return objectType; } - if (isConstEnumObjectType(objectType) && indexExpression.kind !== SyntaxKind.StringLiteral) { + if (isConstEnumObjectType(objectType) && !isStringLiteralLike(indexExpression)) { error(indexExpression, Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal); return errorType; } @@ -30150,7 +30150,7 @@ namespace ts { return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression && isConstantMemberAccess((node).expression) || node.kind === SyntaxKind.ElementAccessExpression && isConstantMemberAccess((node).expression) && - (node).argumentExpression.kind === SyntaxKind.StringLiteral; + isStringLiteralLike((node).argumentExpression); } function checkEnumDeclaration(node: EnumDeclaration) { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 06b3fb53ec180..8bc226a47e136 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -3249,9 +3249,10 @@ namespace ts { const substitute = createLiteral(constantValue); if (!compilerOptions.removeComments) { - const propertyName = isPropertyAccessExpression(node) - ? declarationNameToString(node.name) - : getTextOfNode(node.argumentExpression); + const originalNode = getOriginalNode(node, isAccessExpression); + const propertyName = isPropertyAccessExpression(originalNode) + ? declarationNameToString(originalNode.name) + : getTextOfNode(originalNode.argumentExpression); addSyntheticTrailingComment(substitute, SyntaxKind.MultiLineCommentTrivia, ` ${propertyName} `); } diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index 0d278197c9bf5..abfd41c6faa7c 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -5,15 +5,16 @@ tests/cases/compiler/constEnumErrors.ts(14,9): error TS2474: const enum member i tests/cases/compiler/constEnumErrors.ts(15,10): error TS2474: const enum member initializers can only contain literal values and other computed enum values. tests/cases/compiler/constEnumErrors.ts(22,13): error TS2476: A const enum member can only be accessed using a string literal. tests/cases/compiler/constEnumErrors.ts(24,13): error TS2476: A const enum member can only be accessed using a string literal. -tests/cases/compiler/constEnumErrors.ts(26,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. -tests/cases/compiler/constEnumErrors.ts(27,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. -tests/cases/compiler/constEnumErrors.ts(32,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. -tests/cases/compiler/constEnumErrors.ts(40,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. +tests/cases/compiler/constEnumErrors.ts(25,13): error TS2476: A const enum member can only be accessed using a string literal. +tests/cases/compiler/constEnumErrors.ts(27,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +tests/cases/compiler/constEnumErrors.ts(28,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +tests/cases/compiler/constEnumErrors.ts(33,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. tests/cases/compiler/constEnumErrors.ts(41,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. -tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'. +tests/cases/compiler/constEnumErrors.ts(42,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. +tests/cases/compiler/constEnumErrors.ts(43,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'. -==== tests/cases/compiler/constEnumErrors.ts (13 errors) ==== +==== tests/cases/compiler/constEnumErrors.ts (14 errors) ==== const enum E { ~ !!! error TS2567: Enum declarations can only merge with namespace or other enum declarations. @@ -29,7 +30,7 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member const enum E1 { // illegal case // forward reference to the element of the same enum - X = Y, + X = Y, ~ !!! error TS2651: A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums. // forward reference to the element of the same enum @@ -52,6 +53,9 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member var y1 = E2[name]; ~~~~ !!! error TS2476: A const enum member can only be accessed using a string literal. + var y2 = E2[`${name}`]; + ~~~~~~~~~ +!!! error TS2476: A const enum member can only be accessed using a string literal. var x = E2; ~~ diff --git a/tests/baselines/reference/constEnumErrors.js b/tests/baselines/reference/constEnumErrors.js index 4afd98982f014..3614059d62942 100644 --- a/tests/baselines/reference/constEnumErrors.js +++ b/tests/baselines/reference/constEnumErrors.js @@ -10,7 +10,7 @@ module E { const enum E1 { // illegal case // forward reference to the element of the same enum - X = Y, + X = Y, // forward reference to the element of the same enum Y = E1.Z, Y1 = E1["Z"] @@ -23,6 +23,7 @@ const enum E2 { var y0 = E2[1] var name = "A"; var y1 = E2[name]; +var y2 = E2[`${name}`]; var x = E2; var y = [E2]; @@ -51,6 +52,7 @@ var E; var y0 = E2[1]; var name = "A"; var y1 = E2[name]; +var y2 = E2["" + name]; var x = E2; var y = [E2]; function foo(t) { diff --git a/tests/baselines/reference/constEnumErrors.symbols b/tests/baselines/reference/constEnumErrors.symbols index 727cecb67551e..d3d37e379ef5c 100644 --- a/tests/baselines/reference/constEnumErrors.symbols +++ b/tests/baselines/reference/constEnumErrors.symbols @@ -18,7 +18,7 @@ const enum E1 { // illegal case // forward reference to the element of the same enum - X = Y, + X = Y, >X : Symbol(E1.X, Decl(constEnumErrors.ts, 8, 15)) >Y : Symbol(E1.Y, Decl(constEnumErrors.ts, 11, 10)) @@ -51,57 +51,62 @@ var y1 = E2[name]; >E2 : Symbol(E2, Decl(constEnumErrors.ts, 15, 1)) >name : Symbol(name, Decl(constEnumErrors.ts, 22, 3)) +var y2 = E2[`${name}`]; +>y2 : Symbol(y2, Decl(constEnumErrors.ts, 24, 3)) +>E2 : Symbol(E2, Decl(constEnumErrors.ts, 15, 1)) +>name : Symbol(name, Decl(constEnumErrors.ts, 22, 3)) + var x = E2; ->x : Symbol(x, Decl(constEnumErrors.ts, 25, 3)) +>x : Symbol(x, Decl(constEnumErrors.ts, 26, 3)) >E2 : Symbol(E2, Decl(constEnumErrors.ts, 15, 1)) var y = [E2]; ->y : Symbol(y, Decl(constEnumErrors.ts, 26, 3)) +>y : Symbol(y, Decl(constEnumErrors.ts, 27, 3)) >E2 : Symbol(E2, Decl(constEnumErrors.ts, 15, 1)) function foo(t: any): void { ->foo : Symbol(foo, Decl(constEnumErrors.ts, 26, 13)) ->t : Symbol(t, Decl(constEnumErrors.ts, 28, 13)) +>foo : Symbol(foo, Decl(constEnumErrors.ts, 27, 13)) +>t : Symbol(t, Decl(constEnumErrors.ts, 29, 13)) } foo(E2); ->foo : Symbol(foo, Decl(constEnumErrors.ts, 26, 13)) +>foo : Symbol(foo, Decl(constEnumErrors.ts, 27, 13)) >E2 : Symbol(E2, Decl(constEnumErrors.ts, 15, 1)) const enum NaNOrInfinity { ->NaNOrInfinity : Symbol(NaNOrInfinity, Decl(constEnumErrors.ts, 31, 8)) +>NaNOrInfinity : Symbol(NaNOrInfinity, Decl(constEnumErrors.ts, 32, 8)) A = 9007199254740992, ->A : Symbol(NaNOrInfinity.A, Decl(constEnumErrors.ts, 33, 26)) +>A : Symbol(NaNOrInfinity.A, Decl(constEnumErrors.ts, 34, 26)) B = A * A, ->B : Symbol(NaNOrInfinity.B, Decl(constEnumErrors.ts, 34, 25)) ->A : Symbol(NaNOrInfinity.A, Decl(constEnumErrors.ts, 33, 26)) ->A : Symbol(NaNOrInfinity.A, Decl(constEnumErrors.ts, 33, 26)) +>B : Symbol(NaNOrInfinity.B, Decl(constEnumErrors.ts, 35, 25)) +>A : Symbol(NaNOrInfinity.A, Decl(constEnumErrors.ts, 34, 26)) +>A : Symbol(NaNOrInfinity.A, Decl(constEnumErrors.ts, 34, 26)) C = B * B, ->C : Symbol(NaNOrInfinity.C, Decl(constEnumErrors.ts, 35, 14)) ->B : Symbol(NaNOrInfinity.B, Decl(constEnumErrors.ts, 34, 25)) ->B : Symbol(NaNOrInfinity.B, Decl(constEnumErrors.ts, 34, 25)) +>C : Symbol(NaNOrInfinity.C, Decl(constEnumErrors.ts, 36, 14)) +>B : Symbol(NaNOrInfinity.B, Decl(constEnumErrors.ts, 35, 25)) +>B : Symbol(NaNOrInfinity.B, Decl(constEnumErrors.ts, 35, 25)) D = C * C, ->D : Symbol(NaNOrInfinity.D, Decl(constEnumErrors.ts, 36, 14)) ->C : Symbol(NaNOrInfinity.C, Decl(constEnumErrors.ts, 35, 14)) ->C : Symbol(NaNOrInfinity.C, Decl(constEnumErrors.ts, 35, 14)) +>D : Symbol(NaNOrInfinity.D, Decl(constEnumErrors.ts, 37, 14)) +>C : Symbol(NaNOrInfinity.C, Decl(constEnumErrors.ts, 36, 14)) +>C : Symbol(NaNOrInfinity.C, Decl(constEnumErrors.ts, 36, 14)) E = D * D, ->E : Symbol(NaNOrInfinity.E, Decl(constEnumErrors.ts, 37, 14)) ->D : Symbol(NaNOrInfinity.D, Decl(constEnumErrors.ts, 36, 14)) ->D : Symbol(NaNOrInfinity.D, Decl(constEnumErrors.ts, 36, 14)) +>E : Symbol(NaNOrInfinity.E, Decl(constEnumErrors.ts, 38, 14)) +>D : Symbol(NaNOrInfinity.D, Decl(constEnumErrors.ts, 37, 14)) +>D : Symbol(NaNOrInfinity.D, Decl(constEnumErrors.ts, 37, 14)) F = E * E, // overflow ->F : Symbol(NaNOrInfinity.F, Decl(constEnumErrors.ts, 38, 14)) ->E : Symbol(NaNOrInfinity.E, Decl(constEnumErrors.ts, 37, 14)) ->E : Symbol(NaNOrInfinity.E, Decl(constEnumErrors.ts, 37, 14)) +>F : Symbol(NaNOrInfinity.F, Decl(constEnumErrors.ts, 39, 14)) +>E : Symbol(NaNOrInfinity.E, Decl(constEnumErrors.ts, 38, 14)) +>E : Symbol(NaNOrInfinity.E, Decl(constEnumErrors.ts, 38, 14)) G = 1 / 0, // overflow ->G : Symbol(NaNOrInfinity.G, Decl(constEnumErrors.ts, 39, 14)) +>G : Symbol(NaNOrInfinity.G, Decl(constEnumErrors.ts, 40, 14)) H = 0 / 0 // NaN ->H : Symbol(NaNOrInfinity.H, Decl(constEnumErrors.ts, 40, 14)) +>H : Symbol(NaNOrInfinity.H, Decl(constEnumErrors.ts, 41, 14)) } diff --git a/tests/baselines/reference/constEnumErrors.types b/tests/baselines/reference/constEnumErrors.types index f0ebb60815c32..d2d65e3196877 100644 --- a/tests/baselines/reference/constEnumErrors.types +++ b/tests/baselines/reference/constEnumErrors.types @@ -19,7 +19,7 @@ const enum E1 { // illegal case // forward reference to the element of the same enum - X = Y, + X = Y, >X : E1 >Y : E1 @@ -60,6 +60,13 @@ var y1 = E2[name]; >E2 : typeof E2 >name : string +var y2 = E2[`${name}`]; +>y2 : any +>E2[`${name}`] : any +>E2 : typeof E2 +>`${name}` : string +>name : string + var x = E2; >x : typeof E2 >E2 : typeof E2 diff --git a/tests/baselines/reference/constEnumSyntheticNodesComments.js b/tests/baselines/reference/constEnumSyntheticNodesComments.js new file mode 100644 index 0000000000000..511b5127e5a76 --- /dev/null +++ b/tests/baselines/reference/constEnumSyntheticNodesComments.js @@ -0,0 +1,36 @@ +//// [constEnumSyntheticNodesComments.ts] +const enum En { A, B, C, D } + +function assert(x: T) { + return x; +} + +function verify(a: En) { + switch (a) { + case En.A: + return assert<0>(a); + case En["B"]: + return assert<1>(a); + case En[`C`]: + return assert<2>(a); + case En["\u{44}"]: + return assert<3>(a); + } +} + +//// [constEnumSyntheticNodesComments.js] +function assert(x) { + return x; +} +function verify(a) { + switch (a) { + case 0 /* A */: + return assert(a); + case 1 /* "B" */: + return assert(a); + case 2 /* `C` */: + return assert(a); + case 3 /* "\u{44}" */: + return assert(a); + } +} diff --git a/tests/baselines/reference/constEnumSyntheticNodesComments.symbols b/tests/baselines/reference/constEnumSyntheticNodesComments.symbols new file mode 100644 index 0000000000000..cfd2e9bf75b9d --- /dev/null +++ b/tests/baselines/reference/constEnumSyntheticNodesComments.symbols @@ -0,0 +1,60 @@ +=== tests/cases/compiler/constEnumSyntheticNodesComments.ts === +const enum En { A, B, C, D } +>En : Symbol(En, Decl(constEnumSyntheticNodesComments.ts, 0, 0)) +>A : Symbol(En.A, Decl(constEnumSyntheticNodesComments.ts, 0, 15)) +>B : Symbol(En.B, Decl(constEnumSyntheticNodesComments.ts, 0, 18)) +>C : Symbol(En.C, Decl(constEnumSyntheticNodesComments.ts, 0, 21)) +>D : Symbol(En.D, Decl(constEnumSyntheticNodesComments.ts, 0, 24)) + +function assert(x: T) { +>assert : Symbol(assert, Decl(constEnumSyntheticNodesComments.ts, 0, 28)) +>T : Symbol(T, Decl(constEnumSyntheticNodesComments.ts, 2, 16)) +>x : Symbol(x, Decl(constEnumSyntheticNodesComments.ts, 2, 19)) +>T : Symbol(T, Decl(constEnumSyntheticNodesComments.ts, 2, 16)) + + return x; +>x : Symbol(x, Decl(constEnumSyntheticNodesComments.ts, 2, 19)) +} + +function verify(a: En) { +>verify : Symbol(verify, Decl(constEnumSyntheticNodesComments.ts, 4, 1)) +>a : Symbol(a, Decl(constEnumSyntheticNodesComments.ts, 6, 16)) +>En : Symbol(En, Decl(constEnumSyntheticNodesComments.ts, 0, 0)) + + switch (a) { +>a : Symbol(a, Decl(constEnumSyntheticNodesComments.ts, 6, 16)) + + case En.A: +>En.A : Symbol(En.A, Decl(constEnumSyntheticNodesComments.ts, 0, 15)) +>En : Symbol(En, Decl(constEnumSyntheticNodesComments.ts, 0, 0)) +>A : Symbol(En.A, Decl(constEnumSyntheticNodesComments.ts, 0, 15)) + + return assert<0>(a); +>assert : Symbol(assert, Decl(constEnumSyntheticNodesComments.ts, 0, 28)) +>a : Symbol(a, Decl(constEnumSyntheticNodesComments.ts, 6, 16)) + + case En["B"]: +>En : Symbol(En, Decl(constEnumSyntheticNodesComments.ts, 0, 0)) +>"B" : Symbol(En.B, Decl(constEnumSyntheticNodesComments.ts, 0, 18)) + + return assert<1>(a); +>assert : Symbol(assert, Decl(constEnumSyntheticNodesComments.ts, 0, 28)) +>a : Symbol(a, Decl(constEnumSyntheticNodesComments.ts, 6, 16)) + + case En[`C`]: +>En : Symbol(En, Decl(constEnumSyntheticNodesComments.ts, 0, 0)) +>`C` : Symbol(En.C, Decl(constEnumSyntheticNodesComments.ts, 0, 21)) + + return assert<2>(a); +>assert : Symbol(assert, Decl(constEnumSyntheticNodesComments.ts, 0, 28)) +>a : Symbol(a, Decl(constEnumSyntheticNodesComments.ts, 6, 16)) + + case En["\u{44}"]: +>En : Symbol(En, Decl(constEnumSyntheticNodesComments.ts, 0, 0)) +>"\u{44}" : Symbol(En.D, Decl(constEnumSyntheticNodesComments.ts, 0, 24)) + + return assert<3>(a); +>assert : Symbol(assert, Decl(constEnumSyntheticNodesComments.ts, 0, 28)) +>a : Symbol(a, Decl(constEnumSyntheticNodesComments.ts, 6, 16)) + } +} diff --git a/tests/baselines/reference/constEnumSyntheticNodesComments.types b/tests/baselines/reference/constEnumSyntheticNodesComments.types new file mode 100644 index 0000000000000..c02880ffdb53b --- /dev/null +++ b/tests/baselines/reference/constEnumSyntheticNodesComments.types @@ -0,0 +1,64 @@ +=== tests/cases/compiler/constEnumSyntheticNodesComments.ts === +const enum En { A, B, C, D } +>En : En +>A : En.A +>B : En.B +>C : En.C +>D : En.D + +function assert(x: T) { +>assert : (x: T) => T +>x : T + + return x; +>x : T +} + +function verify(a: En) { +>verify : (a: En) => 0 | 1 | 2 | 3 +>a : En + + switch (a) { +>a : En + + case En.A: +>En.A : En.A +>En : typeof En +>A : En.A + + return assert<0>(a); +>assert<0>(a) : 0 +>assert : (x: T) => T +>a : En.A + + case En["B"]: +>En["B"] : En.B +>En : typeof En +>"B" : "B" + + return assert<1>(a); +>assert<1>(a) : 1 +>assert : (x: T) => T +>a : En.B + + case En[`C`]: +>En[`C`] : En.C +>En : typeof En +>`C` : "C" + + return assert<2>(a); +>assert<2>(a) : 2 +>assert : (x: T) => T +>a : En.C + + case En["\u{44}"]: +>En["\u{44}"] : En.D +>En : typeof En +>"\u{44}" : "D" + + return assert<3>(a); +>assert<3>(a) : 3 +>assert : (x: T) => T +>a : En.D + } +} diff --git a/tests/baselines/reference/constEnums.js b/tests/baselines/reference/constEnums.js index 893872b410082..dc48951f7f57f 100644 --- a/tests/baselines/reference/constEnums.js +++ b/tests/baselines/reference/constEnums.js @@ -35,6 +35,7 @@ const enum Enum1 { W2 = Enum1.A0, W3 = Enum1["A0"], W4 = Enum1["W"], + W5 = Enum1[`V`], } @@ -54,6 +55,7 @@ module A { export module C { export const enum E { V3 = A.B.C.E["V2"] & 200, + V4 = A.B.C.E[`V1`] << 1, } } } @@ -134,7 +136,7 @@ function foo(x: Enum1) { case Enum1.R: case Enum1.S: case Enum1["T"]: - case Enum1.U: + case Enum1[`U`]: case Enum1.V: case Enum1.W: case Enum1.W1: @@ -207,7 +209,7 @@ function foo(x) { case 0 /* R */: case 0 /* S */: case 11 /* "T" */: - case 11 /* U */: + case 11 /* `U` */: case 11 /* V */: case 11 /* W */: case 100 /* W1 */: diff --git a/tests/baselines/reference/constEnums.symbols b/tests/baselines/reference/constEnums.symbols index 0046d08f37d4e..0f0536734a044 100644 --- a/tests/baselines/reference/constEnums.symbols +++ b/tests/baselines/reference/constEnums.symbols @@ -128,220 +128,236 @@ const enum Enum1 { >W4 : Symbol(Enum1.W4, Decl(constEnums.ts, 34, 21)) >Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1)) >"W" : Symbol(Enum1.W, Decl(constEnums.ts, 28, 15)) + + W5 = Enum1[`V`], +>W5 : Symbol(Enum1.W5, Decl(constEnums.ts, 35, 20)) +>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1)) +>`V` : Symbol(Enum1.V, Decl(constEnums.ts, 27, 14)) } module A { ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) export module B { ->B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) +>B : Symbol(B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) export module C { ->C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) +>C : Symbol(C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) export const enum E { ->E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) +>E : Symbol(E, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) V1 = 1, ->V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33)) +>V1 : Symbol(I.V1, Decl(constEnums.ts, 43, 33)) V2 = A.B.C.E.V1 | 100 ->V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23)) ->A.B.C.E.V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33)) ->A.B.C.E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->A.B.C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->A.B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) ->B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33)) +>V2 : Symbol(I.V2, Decl(constEnums.ts, 44, 23)) +>A.B.C.E.V1 : Symbol(I.V1, Decl(constEnums.ts, 43, 33)) +>A.B.C.E : Symbol(E, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>A.B.C : Symbol(C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>A.B : Symbol(B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) +>B : Symbol(B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>C : Symbol(C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>E : Symbol(E, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>V1 : Symbol(I.V1, Decl(constEnums.ts, 43, 33)) } } } } module A { ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) export module B { ->B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) +>B : Symbol(B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) export module C { ->C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) +>C : Symbol(C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) export const enum E { ->E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) +>E : Symbol(E, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) V3 = A.B.C.E["V2"] & 200, ->V3 : Symbol(I.V3, Decl(constEnums.ts, 53, 33)) ->A.B.C.E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->A.B.C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->A.B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) ->B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->"V2" : Symbol(I.V2, Decl(constEnums.ts, 43, 23)) +>V3 : Symbol(I.V3, Decl(constEnums.ts, 54, 33)) +>A.B.C.E : Symbol(E, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>A.B.C : Symbol(C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>A.B : Symbol(B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) +>B : Symbol(B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>C : Symbol(C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>E : Symbol(E, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>"V2" : Symbol(I.V2, Decl(constEnums.ts, 44, 23)) + + V4 = A.B.C.E[`V1`] << 1, +>V4 : Symbol(I.V4, Decl(constEnums.ts, 55, 41)) +>A.B.C.E : Symbol(E, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>A.B.C : Symbol(C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>A.B : Symbol(B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) +>B : Symbol(B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>C : Symbol(C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>E : Symbol(E, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>`V1` : Symbol(I.V1, Decl(constEnums.ts, 43, 33)) } } } } module A1 { ->A1 : Symbol(A1, Decl(constEnums.ts, 58, 1)) +>A1 : Symbol(A1, Decl(constEnums.ts, 60, 1)) export module B { ->B : Symbol(B, Decl(constEnums.ts, 60, 11)) +>B : Symbol(B, Decl(constEnums.ts, 62, 11)) export module C { ->C : Symbol(C, Decl(constEnums.ts, 61, 21)) +>C : Symbol(C, Decl(constEnums.ts, 63, 21)) export const enum E { ->E : Symbol(E, Decl(constEnums.ts, 62, 25)) +>E : Symbol(E, Decl(constEnums.ts, 64, 25)) V1 = 10, ->V1 : Symbol(E.V1, Decl(constEnums.ts, 63, 33)) +>V1 : Symbol(E.V1, Decl(constEnums.ts, 65, 33)) V2 = 110, ->V2 : Symbol(E.V2, Decl(constEnums.ts, 64, 24)) +>V2 : Symbol(E.V2, Decl(constEnums.ts, 66, 24)) } } } } module A2 { ->A2 : Symbol(A2, Decl(constEnums.ts, 69, 1)) +>A2 : Symbol(A2, Decl(constEnums.ts, 71, 1)) export module B { ->B : Symbol(B, Decl(constEnums.ts, 71, 11)) +>B : Symbol(B, Decl(constEnums.ts, 73, 11)) export module C { ->C : Symbol(C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9)) +>C : Symbol(C, Decl(constEnums.ts, 74, 21), Decl(constEnums.ts, 80, 9)) export const enum E { ->E : Symbol(E, Decl(constEnums.ts, 73, 25)) +>E : Symbol(E, Decl(constEnums.ts, 75, 25)) V1 = 10, ->V1 : Symbol(E.V1, Decl(constEnums.ts, 74, 33)) +>V1 : Symbol(E.V1, Decl(constEnums.ts, 76, 33)) V2 = 110, ->V2 : Symbol(E.V2, Decl(constEnums.ts, 75, 24)) +>V2 : Symbol(E.V2, Decl(constEnums.ts, 77, 24)) } } // module C will be classified as value export module C { ->C : Symbol(C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9)) +>C : Symbol(C, Decl(constEnums.ts, 74, 21), Decl(constEnums.ts, 80, 9)) var x = 1 ->x : Symbol(x, Decl(constEnums.ts, 81, 15)) +>x : Symbol(x, Decl(constEnums.ts, 83, 15)) } } } import I = A.B.C.E; ->I : Symbol(I, Decl(constEnums.ts, 84, 1)) ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) ->B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) +>I : Symbol(I, Decl(constEnums.ts, 86, 1)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) +>B : Symbol(A.B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>C : Symbol(A.B.C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>E : Symbol(I, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) import I1 = A1.B; ->I1 : Symbol(I1, Decl(constEnums.ts, 86, 19)) ->A1 : Symbol(A1, Decl(constEnums.ts, 58, 1)) ->B : Symbol(I1, Decl(constEnums.ts, 60, 11)) +>I1 : Symbol(I1, Decl(constEnums.ts, 88, 19)) +>A1 : Symbol(A1, Decl(constEnums.ts, 60, 1)) +>B : Symbol(I1, Decl(constEnums.ts, 62, 11)) import I2 = A2.B; ->I2 : Symbol(I2, Decl(constEnums.ts, 87, 17)) ->A2 : Symbol(A2, Decl(constEnums.ts, 69, 1)) ->B : Symbol(I2, Decl(constEnums.ts, 71, 11)) +>I2 : Symbol(I2, Decl(constEnums.ts, 89, 17)) +>A2 : Symbol(A2, Decl(constEnums.ts, 71, 1)) +>B : Symbol(I2, Decl(constEnums.ts, 73, 11)) function foo0(e: I): void { ->foo0 : Symbol(foo0, Decl(constEnums.ts, 88, 17)) ->e : Symbol(e, Decl(constEnums.ts, 90, 14)) ->I : Symbol(I, Decl(constEnums.ts, 84, 1)) +>foo0 : Symbol(foo0, Decl(constEnums.ts, 90, 17)) +>e : Symbol(e, Decl(constEnums.ts, 92, 14)) +>I : Symbol(I, Decl(constEnums.ts, 86, 1)) if (e === I.V1) { ->e : Symbol(e, Decl(constEnums.ts, 90, 14)) ->I.V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33)) ->I : Symbol(I, Decl(constEnums.ts, 84, 1)) ->V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33)) +>e : Symbol(e, Decl(constEnums.ts, 92, 14)) +>I.V1 : Symbol(I.V1, Decl(constEnums.ts, 43, 33)) +>I : Symbol(I, Decl(constEnums.ts, 86, 1)) +>V1 : Symbol(I.V1, Decl(constEnums.ts, 43, 33)) } else if (e === I.V2) { ->e : Symbol(e, Decl(constEnums.ts, 90, 14)) ->I.V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23)) ->I : Symbol(I, Decl(constEnums.ts, 84, 1)) ->V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23)) +>e : Symbol(e, Decl(constEnums.ts, 92, 14)) +>I.V2 : Symbol(I.V2, Decl(constEnums.ts, 44, 23)) +>I : Symbol(I, Decl(constEnums.ts, 86, 1)) +>V2 : Symbol(I.V2, Decl(constEnums.ts, 44, 23)) } } function foo1(e: I1.C.E): void { ->foo1 : Symbol(foo1, Decl(constEnums.ts, 95, 1)) ->e : Symbol(e, Decl(constEnums.ts, 97, 14)) ->I1 : Symbol(I1, Decl(constEnums.ts, 86, 19)) ->C : Symbol(I1.C, Decl(constEnums.ts, 61, 21)) ->E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25)) +>foo1 : Symbol(foo1, Decl(constEnums.ts, 97, 1)) +>e : Symbol(e, Decl(constEnums.ts, 99, 14)) +>I1 : Symbol(I1, Decl(constEnums.ts, 88, 19)) +>C : Symbol(I1.C, Decl(constEnums.ts, 63, 21)) +>E : Symbol(I1.C.E, Decl(constEnums.ts, 64, 25)) if (e === I1.C.E.V1) { ->e : Symbol(e, Decl(constEnums.ts, 97, 14)) ->I1.C.E.V1 : Symbol(I1.C.E.V1, Decl(constEnums.ts, 63, 33)) ->I1.C.E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25)) ->I1.C : Symbol(I1.C, Decl(constEnums.ts, 61, 21)) ->I1 : Symbol(I1, Decl(constEnums.ts, 86, 19)) ->C : Symbol(I1.C, Decl(constEnums.ts, 61, 21)) ->E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25)) ->V1 : Symbol(I1.C.E.V1, Decl(constEnums.ts, 63, 33)) +>e : Symbol(e, Decl(constEnums.ts, 99, 14)) +>I1.C.E.V1 : Symbol(I1.C.E.V1, Decl(constEnums.ts, 65, 33)) +>I1.C.E : Symbol(I1.C.E, Decl(constEnums.ts, 64, 25)) +>I1.C : Symbol(I1.C, Decl(constEnums.ts, 63, 21)) +>I1 : Symbol(I1, Decl(constEnums.ts, 88, 19)) +>C : Symbol(I1.C, Decl(constEnums.ts, 63, 21)) +>E : Symbol(I1.C.E, Decl(constEnums.ts, 64, 25)) +>V1 : Symbol(I1.C.E.V1, Decl(constEnums.ts, 65, 33)) } else if (e === I1.C.E.V2) { ->e : Symbol(e, Decl(constEnums.ts, 97, 14)) ->I1.C.E.V2 : Symbol(I1.C.E.V2, Decl(constEnums.ts, 64, 24)) ->I1.C.E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25)) ->I1.C : Symbol(I1.C, Decl(constEnums.ts, 61, 21)) ->I1 : Symbol(I1, Decl(constEnums.ts, 86, 19)) ->C : Symbol(I1.C, Decl(constEnums.ts, 61, 21)) ->E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25)) ->V2 : Symbol(I1.C.E.V2, Decl(constEnums.ts, 64, 24)) +>e : Symbol(e, Decl(constEnums.ts, 99, 14)) +>I1.C.E.V2 : Symbol(I1.C.E.V2, Decl(constEnums.ts, 66, 24)) +>I1.C.E : Symbol(I1.C.E, Decl(constEnums.ts, 64, 25)) +>I1.C : Symbol(I1.C, Decl(constEnums.ts, 63, 21)) +>I1 : Symbol(I1, Decl(constEnums.ts, 88, 19)) +>C : Symbol(I1.C, Decl(constEnums.ts, 63, 21)) +>E : Symbol(I1.C.E, Decl(constEnums.ts, 64, 25)) +>V2 : Symbol(I1.C.E.V2, Decl(constEnums.ts, 66, 24)) } } function foo2(e: I2.C.E): void { ->foo2 : Symbol(foo2, Decl(constEnums.ts, 102, 1)) ->e : Symbol(e, Decl(constEnums.ts, 104, 14)) ->I2 : Symbol(I2, Decl(constEnums.ts, 87, 17)) ->C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9)) ->E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25)) +>foo2 : Symbol(foo2, Decl(constEnums.ts, 104, 1)) +>e : Symbol(e, Decl(constEnums.ts, 106, 14)) +>I2 : Symbol(I2, Decl(constEnums.ts, 89, 17)) +>C : Symbol(I2.C, Decl(constEnums.ts, 74, 21), Decl(constEnums.ts, 80, 9)) +>E : Symbol(I2.C.E, Decl(constEnums.ts, 75, 25)) if (e === I2.C.E.V1) { ->e : Symbol(e, Decl(constEnums.ts, 104, 14)) ->I2.C.E.V1 : Symbol(I2.C.E.V1, Decl(constEnums.ts, 74, 33)) ->I2.C.E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25)) ->I2.C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9)) ->I2 : Symbol(I2, Decl(constEnums.ts, 87, 17)) ->C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9)) ->E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25)) ->V1 : Symbol(I2.C.E.V1, Decl(constEnums.ts, 74, 33)) +>e : Symbol(e, Decl(constEnums.ts, 106, 14)) +>I2.C.E.V1 : Symbol(I2.C.E.V1, Decl(constEnums.ts, 76, 33)) +>I2.C.E : Symbol(I2.C.E, Decl(constEnums.ts, 75, 25)) +>I2.C : Symbol(I2.C, Decl(constEnums.ts, 74, 21), Decl(constEnums.ts, 80, 9)) +>I2 : Symbol(I2, Decl(constEnums.ts, 89, 17)) +>C : Symbol(I2.C, Decl(constEnums.ts, 74, 21), Decl(constEnums.ts, 80, 9)) +>E : Symbol(I2.C.E, Decl(constEnums.ts, 75, 25)) +>V1 : Symbol(I2.C.E.V1, Decl(constEnums.ts, 76, 33)) } else if (e === I2.C.E.V2) { ->e : Symbol(e, Decl(constEnums.ts, 104, 14)) ->I2.C.E.V2 : Symbol(I2.C.E.V2, Decl(constEnums.ts, 75, 24)) ->I2.C.E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25)) ->I2.C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9)) ->I2 : Symbol(I2, Decl(constEnums.ts, 87, 17)) ->C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9)) ->E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25)) ->V2 : Symbol(I2.C.E.V2, Decl(constEnums.ts, 75, 24)) +>e : Symbol(e, Decl(constEnums.ts, 106, 14)) +>I2.C.E.V2 : Symbol(I2.C.E.V2, Decl(constEnums.ts, 77, 24)) +>I2.C.E : Symbol(I2.C.E, Decl(constEnums.ts, 75, 25)) +>I2.C : Symbol(I2.C, Decl(constEnums.ts, 74, 21), Decl(constEnums.ts, 80, 9)) +>I2 : Symbol(I2, Decl(constEnums.ts, 89, 17)) +>C : Symbol(I2.C, Decl(constEnums.ts, 74, 21), Decl(constEnums.ts, 80, 9)) +>E : Symbol(I2.C.E, Decl(constEnums.ts, 75, 25)) +>V2 : Symbol(I2.C.E.V2, Decl(constEnums.ts, 77, 24)) } } function foo(x: Enum1) { ->foo : Symbol(foo, Decl(constEnums.ts, 109, 1)) ->x : Symbol(x, Decl(constEnums.ts, 112, 13)) +>foo : Symbol(foo, Decl(constEnums.ts, 111, 1)) +>x : Symbol(x, Decl(constEnums.ts, 114, 13)) >Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1)) switch (x) { ->x : Symbol(x, Decl(constEnums.ts, 112, 13)) +>x : Symbol(x, Decl(constEnums.ts, 114, 13)) case Enum1.A: >Enum1.A : Symbol(Enum1.A, Decl(constEnums.ts, 4, 18)) @@ -447,10 +463,9 @@ function foo(x: Enum1) { >Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1)) >"T" : Symbol(Enum1.T, Decl(constEnums.ts, 25, 14)) - case Enum1.U: ->Enum1.U : Symbol(Enum1.U, Decl(constEnums.ts, 26, 14)) + case Enum1[`U`]: >Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1)) ->U : Symbol(Enum1.U, Decl(constEnums.ts, 26, 14)) +>`U` : Symbol(Enum1.U, Decl(constEnums.ts, 26, 14)) case Enum1.V: >Enum1.V : Symbol(Enum1.V, Decl(constEnums.ts, 27, 14)) @@ -487,47 +502,47 @@ function foo(x: Enum1) { } function bar(e: A.B.C.E): number { ->bar : Symbol(bar, Decl(constEnums.ts, 144, 1)) ->e : Symbol(e, Decl(constEnums.ts, 146, 13)) ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) ->B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) +>bar : Symbol(bar, Decl(constEnums.ts, 146, 1)) +>e : Symbol(e, Decl(constEnums.ts, 148, 13)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) +>B : Symbol(A.B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>C : Symbol(A.B.C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>E : Symbol(I, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) switch (e) { ->e : Symbol(e, Decl(constEnums.ts, 146, 13)) +>e : Symbol(e, Decl(constEnums.ts, 148, 13)) case A.B.C.E.V1: return 1; ->A.B.C.E.V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33)) ->A.B.C.E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->A.B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) ->B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33)) +>A.B.C.E.V1 : Symbol(I.V1, Decl(constEnums.ts, 43, 33)) +>A.B.C.E : Symbol(I, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>A.B : Symbol(A.B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) +>B : Symbol(A.B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>C : Symbol(A.B.C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>E : Symbol(I, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>V1 : Symbol(I.V1, Decl(constEnums.ts, 43, 33)) case A.B.C.E.V2: return 1; ->A.B.C.E.V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23)) ->A.B.C.E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->A.B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) ->B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23)) +>A.B.C.E.V2 : Symbol(I.V2, Decl(constEnums.ts, 44, 23)) +>A.B.C.E : Symbol(I, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>A.B : Symbol(A.B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) +>B : Symbol(A.B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>C : Symbol(A.B.C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>E : Symbol(I, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>V2 : Symbol(I.V2, Decl(constEnums.ts, 44, 23)) case A.B.C.E.V3: return 1; ->A.B.C.E.V3 : Symbol(I.V3, Decl(constEnums.ts, 53, 33)) ->A.B.C.E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->A.B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1)) ->B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10)) ->C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21)) ->E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25)) ->V3 : Symbol(I.V3, Decl(constEnums.ts, 53, 33)) +>A.B.C.E.V3 : Symbol(I.V3, Decl(constEnums.ts, 54, 33)) +>A.B.C.E : Symbol(I, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>A.B : Symbol(A.B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>A : Symbol(A, Decl(constEnums.ts, 37, 1), Decl(constEnums.ts, 49, 1)) +>B : Symbol(A.B, Decl(constEnums.ts, 40, 10), Decl(constEnums.ts, 51, 10)) +>C : Symbol(A.B.C, Decl(constEnums.ts, 41, 21), Decl(constEnums.ts, 52, 21)) +>E : Symbol(I, Decl(constEnums.ts, 42, 25), Decl(constEnums.ts, 53, 25)) +>V3 : Symbol(I.V3, Decl(constEnums.ts, 54, 33)) } } diff --git a/tests/baselines/reference/constEnums.types b/tests/baselines/reference/constEnums.types index c85f5f3836ce0..fc3caf5514dab 100644 --- a/tests/baselines/reference/constEnums.types +++ b/tests/baselines/reference/constEnums.types @@ -172,6 +172,12 @@ const enum Enum1 { >Enum1["W"] : Enum1 >Enum1 : typeof Enum1 >"W" : "W" + + W5 = Enum1[`V`], +>W5 : Enum1 +>Enum1[`V`] : Enum1 +>Enum1 : typeof Enum1 +>`V` : "V" } @@ -222,6 +228,20 @@ module A { >E : typeof E >"V2" : "V2" >200 : 200 + + V4 = A.B.C.E[`V1`] << 1, +>V4 : E +>A.B.C.E[`V1`] << 1 : number +>A.B.C.E[`V1`] : E +>A.B.C.E : typeof E +>A.B.C : typeof C +>A.B : typeof B +>A : typeof A +>B : typeof B +>C : typeof C +>E : typeof E +>`V1` : "V1" +>1 : 1 } } } @@ -485,10 +505,10 @@ function foo(x: Enum1) { >Enum1 : typeof Enum1 >"T" : "T" - case Enum1.U: ->Enum1.U : Enum1 + case Enum1[`U`]: +>Enum1[`U`] : Enum1 >Enum1 : typeof Enum1 ->U : Enum1 +>`U` : "U" case Enum1.V: >Enum1.V : Enum1 diff --git a/tests/cases/compiler/constEnumErrors.ts b/tests/cases/compiler/constEnumErrors.ts index be45ed8363221..ca2289ef3bf33 100644 --- a/tests/cases/compiler/constEnumErrors.ts +++ b/tests/cases/compiler/constEnumErrors.ts @@ -10,7 +10,7 @@ module E { const enum E1 { // illegal case // forward reference to the element of the same enum - X = Y, + X = Y, // forward reference to the element of the same enum Y = E1.Z, Y1 = E1["Z"] @@ -23,6 +23,7 @@ const enum E2 { var y0 = E2[1] var name = "A"; var y1 = E2[name]; +var y2 = E2[`${name}`]; var x = E2; var y = [E2]; diff --git a/tests/cases/compiler/constEnumSyntheticNodesComments.ts b/tests/cases/compiler/constEnumSyntheticNodesComments.ts new file mode 100644 index 0000000000000..dfa66ed4679d4 --- /dev/null +++ b/tests/cases/compiler/constEnumSyntheticNodesComments.ts @@ -0,0 +1,18 @@ +const enum En { A, B, C, D } + +function assert(x: T) { + return x; +} + +function verify(a: En) { + switch (a) { + case En.A: + return assert<0>(a); + case En["B"]: + return assert<1>(a); + case En[`C`]: + return assert<2>(a); + case En["\u{44}"]: + return assert<3>(a); + } +} \ No newline at end of file diff --git a/tests/cases/compiler/constEnums.ts b/tests/cases/compiler/constEnums.ts index 617b89e2ba866..0b30fd8983135 100644 --- a/tests/cases/compiler/constEnums.ts +++ b/tests/cases/compiler/constEnums.ts @@ -34,6 +34,7 @@ const enum Enum1 { W2 = Enum1.A0, W3 = Enum1["A0"], W4 = Enum1["W"], + W5 = Enum1[`V`], } @@ -53,6 +54,7 @@ module A { export module C { export const enum E { V3 = A.B.C.E["V2"] & 200, + V4 = A.B.C.E[`V1`] << 1, } } } @@ -133,7 +135,7 @@ function foo(x: Enum1) { case Enum1.R: case Enum1.S: case Enum1["T"]: - case Enum1.U: + case Enum1[`U`]: case Enum1.V: case Enum1.W: case Enum1.W1: From d8038dae7aa21ecc47b925ef523eeefe091f669a Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Fri, 21 Jun 2019 01:05:25 +0300 Subject: [PATCH 03/10] Support template literals in swith with typeof narrowing --- src/compiler/checker.ts | 4 +- .../reference/narrowingByTypeofInSwitch.js | 118 +++++++++++- .../narrowingByTypeofInSwitch.symbols | 141 ++++++++++++++ .../reference/narrowingByTypeofInSwitch.types | 173 ++++++++++++++++++ .../compiler/narrowingByTypeofInSwitch.ts | 50 +++++ 5 files changed, 483 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index abfe768bc3c52..671319e1e2c25 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16913,8 +16913,8 @@ namespace ts { const witnesses: (string | undefined)[] = []; for (const clause of switchStatement.caseBlock.clauses) { if (clause.kind === SyntaxKind.CaseClause) { - if (clause.expression.kind === SyntaxKind.StringLiteral) { - witnesses.push((clause.expression as StringLiteral).text); + if (isStringLiteralLike(clause.expression)) { + witnesses.push(clause.expression.text); continue; } return emptyArray; diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.js b/tests/baselines/reference/narrowingByTypeofInSwitch.js index 2b99da05e1357..f2b4d26c56e54 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.js +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.js @@ -249,7 +249,56 @@ function narrowingNarrows(x: {} | undefined) { default: const _y: {} = x; return; } } - + +/* Template literals */ + +function testUnionWithTempalte(x: Basic) { + switch (typeof x) { + case `number`: assertNumber(x); return; + case `boolean`: assertBoolean(x); return; + case `function`: assertFunction(x); return; + case `symbol`: assertSymbol(x); return; + case `object`: assertObject(x); return; + case `string`: assertString(x); return; + case `undefined`: assertUndefined(x); return; + } + assertNever(x); +} + +function fallThroughTestWithTempalte(x: string | number | boolean | object) { + switch (typeof x) { + case `number`: + assertNumber(x) + case `string`: + assertStringOrNumber(x) + break; + default: + assertObject(x); + case `number`: + case `boolean`: + assertBooleanOrObject(x); + break; + } +} + +function keyofNarrowingWithTemplate(k: keyof S) { + function assertKeyofS(k1: keyof S) { } + switch (typeof k) { + case `number`: assertNumber(k); assertKeyofS(k); return; + case `symbol`: assertSymbol(k); assertKeyofS(k); return; + case `string`: assertString(k); assertKeyofS(k); return; + } +} + +/* Both string literals and template literals */ + +function multipleGenericFuseWithBoth(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { + switch (typeof xy) { + case `function`: return [xy, 1]; + case 'object': return [xy, 'two']; + case `number`: return [xy] + } +} //// [narrowingByTypeofInSwitch.js] function assertNever(x) { @@ -585,3 +634,70 @@ function narrowingNarrows(x) { return; } } +/* Template literals */ +function testUnionWithTempalte(x) { + switch (typeof x) { + case "number": + assertNumber(x); + return; + case "boolean": + assertBoolean(x); + return; + case "function": + assertFunction(x); + return; + case "symbol": + assertSymbol(x); + return; + case "object": + assertObject(x); + return; + case "string": + assertString(x); + return; + case "undefined": + assertUndefined(x); + return; + } + assertNever(x); +} +function fallThroughTestWithTempalte(x) { + switch (typeof x) { + case "number": + assertNumber(x); + case "string": + assertStringOrNumber(x); + break; + default: + assertObject(x); + case "number": + case "boolean": + assertBooleanOrObject(x); + break; + } +} +function keyofNarrowingWithTemplate(k) { + function assertKeyofS(k1) { } + switch (typeof k) { + case "number": + assertNumber(k); + assertKeyofS(k); + return; + case "symbol": + assertSymbol(k); + assertKeyofS(k); + return; + case "string": + assertString(k); + assertKeyofS(k); + return; + } +} +/* Both string literals and template literals */ +function multipleGenericFuseWithBoth(xy) { + switch (typeof xy) { + case "function": return [xy, 1]; + case 'object': return [xy, 'two']; + case "number": return [xy]; + } +} diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.symbols b/tests/baselines/reference/narrowingByTypeofInSwitch.symbols index f1ff39725b39f..2feb98164ea6d 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.symbols +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.symbols @@ -715,3 +715,144 @@ function narrowingNarrows(x: {} | undefined) { } } +/* Template literals */ + +function testUnionWithTempalte(x: Basic) { +>testUnionWithTempalte : Symbol(testUnionWithTempalte, Decl(narrowingByTypeofInSwitch.ts, 249, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 46, 1)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) + + case `number`: assertNumber(x); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) + + case `boolean`: assertBoolean(x); return; +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) + + case `function`: assertFunction(x); return; +>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) + + case `symbol`: assertSymbol(x); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) + + case `object`: assertObject(x); return; +>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) + + case `string`: assertString(x); return; +>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) + + case `undefined`: assertUndefined(x); return; +>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) + } + assertNever(x); +>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 253, 31)) +} + +function fallThroughTestWithTempalte(x: string | number | boolean | object) { +>fallThroughTestWithTempalte : Symbol(fallThroughTestWithTempalte, Decl(narrowingByTypeofInSwitch.ts, 264, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 266, 37)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 266, 37)) + + case `number`: + assertNumber(x) +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 266, 37)) + + case `string`: + assertStringOrNumber(x) +>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 38, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 266, 37)) + + break; + default: + assertObject(x); +>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 266, 37)) + + case `number`: + case `boolean`: + assertBooleanOrObject(x); +>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 266, 37)) + + break; + } +} + +function keyofNarrowingWithTemplate(k: keyof S) { +>keyofNarrowingWithTemplate : Symbol(keyofNarrowingWithTemplate, Decl(narrowingByTypeofInSwitch.ts, 280, 1)) +>S : Symbol(S, Decl(narrowingByTypeofInSwitch.ts, 282, 36)) +>K : Symbol(K, Decl(narrowingByTypeofInSwitch.ts, 282, 49)) +>S : Symbol(S, Decl(narrowingByTypeofInSwitch.ts, 282, 36)) +>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 282, 74)) +>S : Symbol(S, Decl(narrowingByTypeofInSwitch.ts, 282, 36)) + + function assertKeyofS(k1: keyof S) { } +>assertKeyofS : Symbol(assertKeyofS, Decl(narrowingByTypeofInSwitch.ts, 282, 87)) +>k1 : Symbol(k1, Decl(narrowingByTypeofInSwitch.ts, 283, 26)) +>S : Symbol(S, Decl(narrowingByTypeofInSwitch.ts, 282, 36)) + + switch (typeof k) { +>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 282, 74)) + + case `number`: assertNumber(k); assertKeyofS(k); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 282, 74)) +>assertKeyofS : Symbol(assertKeyofS, Decl(narrowingByTypeofInSwitch.ts, 282, 87)) +>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 282, 74)) + + case `symbol`: assertSymbol(k); assertKeyofS(k); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 282, 74)) +>assertKeyofS : Symbol(assertKeyofS, Decl(narrowingByTypeofInSwitch.ts, 282, 87)) +>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 282, 74)) + + case `string`: assertString(k); assertKeyofS(k); return; +>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) +>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 282, 74)) +>assertKeyofS : Symbol(assertKeyofS, Decl(narrowingByTypeofInSwitch.ts, 282, 87)) +>k : Symbol(k, Decl(narrowingByTypeofInSwitch.ts, 282, 74)) + } +} + +/* Both string literals and template literals */ + +function multipleGenericFuseWithBoth(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { +>multipleGenericFuseWithBoth : Symbol(multipleGenericFuseWithBoth, Decl(narrowingByTypeofInSwitch.ts, 289, 1)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 293, 37)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 132, 1)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 293, 58)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 134, 31)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 293, 81)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 293, 37)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 293, 58)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 293, 37)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 293, 58)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 293, 37)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 293, 58)) + + switch (typeof xy) { +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 293, 81)) + + case `function`: return [xy, 1]; +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 293, 81)) + + case 'object': return [xy, 'two']; +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 293, 81)) + + case `number`: return [xy] +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 293, 81)) + } +} diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.types b/tests/baselines/reference/narrowingByTypeofInSwitch.types index f823c57770c3a..616dae2922590 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.types +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.types @@ -869,3 +869,176 @@ function narrowingNarrows(x: {} | undefined) { } } +/* Template literals */ + +function testUnionWithTempalte(x: Basic) { +>testUnionWithTempalte : (x: Basic) => void +>x : Basic + + switch (typeof x) { +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : Basic + + case `number`: assertNumber(x); return; +>`number` : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : number + + case `boolean`: assertBoolean(x); return; +>`boolean` : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : boolean + + case `function`: assertFunction(x); return; +>`function` : "function" +>assertFunction(x) : Function +>assertFunction : (x: Function) => Function +>x : Function + + case `symbol`: assertSymbol(x); return; +>`symbol` : "symbol" +>assertSymbol(x) : symbol +>assertSymbol : (x: symbol) => symbol +>x : symbol + + case `object`: assertObject(x); return; +>`object` : "object" +>assertObject(x) : object +>assertObject : (x: object) => object +>x : object + + case `string`: assertString(x); return; +>`string` : "string" +>assertString(x) : string +>assertString : (x: string) => string +>x : string + + case `undefined`: assertUndefined(x); return; +>`undefined` : "undefined" +>assertUndefined(x) : undefined +>assertUndefined : (x: undefined) => undefined +>x : undefined + } + assertNever(x); +>assertNever(x) : never +>assertNever : (x: never) => never +>x : never +} + +function fallThroughTestWithTempalte(x: string | number | boolean | object) { +>fallThroughTestWithTempalte : (x: string | number | boolean | object) => void +>x : string | number | boolean | object + + switch (typeof x) { +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : string | number | boolean | object + + case `number`: +>`number` : "number" + + assertNumber(x) +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : number + + case `string`: +>`string` : "string" + + assertStringOrNumber(x) +>assertStringOrNumber(x) : string | number +>assertStringOrNumber : (x: string | number) => string | number +>x : string | number + + break; + default: + assertObject(x); +>assertObject(x) : object +>assertObject : (x: object) => object +>x : object + + case `number`: +>`number` : "number" + + case `boolean`: +>`boolean` : "boolean" + + assertBooleanOrObject(x); +>assertBooleanOrObject(x) : boolean | object +>assertBooleanOrObject : (x: boolean | object) => boolean | object +>x : boolean | object + + break; + } +} + +function keyofNarrowingWithTemplate(k: keyof S) { +>keyofNarrowingWithTemplate : (k: keyof S) => void +>k : keyof S + + function assertKeyofS(k1: keyof S) { } +>assertKeyofS : (k1: keyof S) => void +>k1 : keyof S + + switch (typeof k) { +>typeof k : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>k : keyof S + + case `number`: assertNumber(k); assertKeyofS(k); return; +>`number` : "number" +>assertNumber(k) : number +>assertNumber : (x: number) => number +>k : keyof S & number +>assertKeyofS(k) : void +>assertKeyofS : (k1: keyof S) => void +>k : keyof S & number + + case `symbol`: assertSymbol(k); assertKeyofS(k); return; +>`symbol` : "symbol" +>assertSymbol(k) : symbol +>assertSymbol : (x: symbol) => symbol +>k : keyof S & symbol +>assertKeyofS(k) : void +>assertKeyofS : (k1: keyof S) => void +>k : keyof S & symbol + + case `string`: assertString(k); assertKeyofS(k); return; +>`string` : "string" +>assertString(k) : string +>assertString : (x: string) => string +>k : keyof S & string +>assertKeyofS(k) : void +>assertKeyofS : (k1: keyof S) => void +>k : keyof S & string + } +} + +/* Both string literals and template literals */ + +function multipleGenericFuseWithBoth(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { +>multipleGenericFuseWithBoth : (xy: X | Y) => [X, number] | [Y, string] | [X | Y] +>xy : X | Y + + switch (typeof xy) { +>typeof xy : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>xy : X | Y + + case `function`: return [xy, 1]; +>`function` : "function" +>[xy, 1] : [X, 1] +>xy : X +>1 : 1 + + case 'object': return [xy, 'two']; +>'object' : "object" +>[xy, 'two'] : [Y, string] +>xy : Y +>'two' : "two" + + case `number`: return [xy] +>`number` : "number" +>[xy] : [(X & number) | (Y & number)] +>xy : (X & number) | (Y & number) + } +} diff --git a/tests/cases/compiler/narrowingByTypeofInSwitch.ts b/tests/cases/compiler/narrowingByTypeofInSwitch.ts index 39f04168684d1..cd726827456e3 100644 --- a/tests/cases/compiler/narrowingByTypeofInSwitch.ts +++ b/tests/cases/compiler/narrowingByTypeofInSwitch.ts @@ -251,3 +251,53 @@ function narrowingNarrows(x: {} | undefined) { default: const _y: {} = x; return; } } + +/* Template literals */ + +function testUnionWithTempalte(x: Basic) { + switch (typeof x) { + case `number`: assertNumber(x); return; + case `boolean`: assertBoolean(x); return; + case `function`: assertFunction(x); return; + case `symbol`: assertSymbol(x); return; + case `object`: assertObject(x); return; + case `string`: assertString(x); return; + case `undefined`: assertUndefined(x); return; + } + assertNever(x); +} + +function fallThroughTestWithTempalte(x: string | number | boolean | object) { + switch (typeof x) { + case `number`: + assertNumber(x) + case `string`: + assertStringOrNumber(x) + break; + default: + assertObject(x); + case `number`: + case `boolean`: + assertBooleanOrObject(x); + break; + } +} + +function keyofNarrowingWithTemplate(k: keyof S) { + function assertKeyofS(k1: keyof S) { } + switch (typeof k) { + case `number`: assertNumber(k); assertKeyofS(k); return; + case `symbol`: assertSymbol(k); assertKeyofS(k); return; + case `string`: assertString(k); assertKeyofS(k); return; + } +} + +/* Both string literals and template literals */ + +function multipleGenericFuseWithBoth(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { + switch (typeof xy) { + case `function`: return [xy, 1]; + case 'object': return [xy, 'two']; + case `number`: return [xy] + } +} \ No newline at end of file From 42e88e71dc113848653b14f4d17d88cb34482e7f Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Fri, 21 Jun 2019 04:34:56 +0300 Subject: [PATCH 04/10] Support template literals in element access discriminant --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 2 +- .../discriminantElementAccessCheck.js | 94 ++++++++++++ .../discriminantElementAccessCheck.symbols | 132 +++++++++++++++++ .../discriminantElementAccessCheck.types | 140 ++++++++++++++++++ .../discriminantElementAccessCheck.ts | 52 +++++++ 6 files changed, 420 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/discriminantElementAccessCheck.js create mode 100644 tests/baselines/reference/discriminantElementAccessCheck.symbols create mode 100644 tests/baselines/reference/discriminantElementAccessCheck.types create mode 100644 tests/cases/compiler/discriminantElementAccessCheck.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1d6627987e151..d23141571f631 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -789,7 +789,7 @@ namespace ts { return expr.kind === SyntaxKind.Identifier || expr.kind === SyntaxKind.ThisKeyword || expr.kind === SyntaxKind.SuperKeyword || (isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || isElementAccessExpression(expr) && - (isStringLiteral(expr.argumentExpression) || isNumericLiteral(expr.argumentExpression)) && + isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 671319e1e2c25..275ac54088999 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16515,7 +16515,7 @@ namespace ts { function getAccessedPropertyName(access: AccessExpression): __String | undefined { return access.kind === SyntaxKind.PropertyAccessExpression ? access.name.escapedText : - isStringLiteral(access.argumentExpression) || isNumericLiteral(access.argumentExpression) ? escapeLeadingUnderscores(access.argumentExpression.text) : + isStringOrNumericLiteralLike(access.argumentExpression) ? escapeLeadingUnderscores(access.argumentExpression.text) : undefined; } diff --git a/tests/baselines/reference/discriminantElementAccessCheck.js b/tests/baselines/reference/discriminantElementAccessCheck.js new file mode 100644 index 0000000000000..7501d007f1f4a --- /dev/null +++ b/tests/baselines/reference/discriminantElementAccessCheck.js @@ -0,0 +1,94 @@ +//// [discriminantElementAccessCheck.ts] +type U = TypeA | TypeB; + +interface TypeA { + kind: 'A'; + a: number; +} +interface TypeB { + kind: 'B'; + b: string; +} + +function assertNever(x: never) { + return x; +} + +function IfWithString(val: U) { + if (val['kind'] === 'B') { + return val.b; + } else { + return val.a; + } +} + +function SwitchWithString(val: U) { + switch (val['kind']) { + case 'A': + return val.a; + case 'B': + return val.b; + default: + return assertNever(val); + } +} + +function IfWithTemplate(val: U) { + if (val[`kind`] === 'B') { + return val.b; + } else { + return val.a; + } +} + +function SwitchWithTemplate(val: U) { + switch (val[`kind`]) { + case 'A': + return val.a; + case 'B': + return val.b; + default: + return assertNever(val); + } +} + +//// [discriminantElementAccessCheck.js] +function assertNever(x) { + return x; +} +function IfWithString(val) { + if (val['kind'] === 'B') { + return val.b; + } + else { + return val.a; + } +} +function SwitchWithString(val) { + switch (val['kind']) { + case 'A': + return val.a; + case 'B': + return val.b; + default: + return assertNever(val); + } +} +function IfWithTemplate(val) { + if (val["kind"] === 'B') { + return val.b; + } + else { + return val.a; + } +} +function SwitchWithTemplate(val) { + switch (val["kind"]) { + case 'A': + return val.a; + case 'B': + return val.b; + default: + return assertNever(val); + } +} diff --git a/tests/baselines/reference/discriminantElementAccessCheck.symbols b/tests/baselines/reference/discriminantElementAccessCheck.symbols new file mode 100644 index 0000000000000..e7e681861e6a0 --- /dev/null +++ b/tests/baselines/reference/discriminantElementAccessCheck.symbols @@ -0,0 +1,132 @@ +=== tests/cases/compiler/discriminantElementAccessCheck.ts === +type U = TypeA | TypeB; +>U : Symbol(U, Decl(discriminantElementAccessCheck.ts, 0, 0)) +>TypeA : Symbol(TypeA, Decl(discriminantElementAccessCheck.ts, 0, 23)) +>TypeB : Symbol(TypeB, Decl(discriminantElementAccessCheck.ts, 5, 1)) + +interface TypeA { +>TypeA : Symbol(TypeA, Decl(discriminantElementAccessCheck.ts, 0, 23)) + + kind: 'A'; +>kind : Symbol(TypeA.kind, Decl(discriminantElementAccessCheck.ts, 2, 17)) + + a: number; +>a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) +} +interface TypeB { +>TypeB : Symbol(TypeB, Decl(discriminantElementAccessCheck.ts, 5, 1)) + + kind: 'B'; +>kind : Symbol(TypeB.kind, Decl(discriminantElementAccessCheck.ts, 6, 17)) + + b: string; +>b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) +} + +function assertNever(x: never) { +>assertNever : Symbol(assertNever, Decl(discriminantElementAccessCheck.ts, 9, 1)) +>x : Symbol(x, Decl(discriminantElementAccessCheck.ts, 11, 21)) + + return x; +>x : Symbol(x, Decl(discriminantElementAccessCheck.ts, 11, 21)) +} + +function IfWithString(val: U) { +>IfWithString : Symbol(IfWithString, Decl(discriminantElementAccessCheck.ts, 13, 1)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 15, 22)) +>U : Symbol(U, Decl(discriminantElementAccessCheck.ts, 0, 0)) + + if (val['kind'] === 'B') { +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 15, 22)) +>'kind' : Symbol(kind, Decl(discriminantElementAccessCheck.ts, 2, 17), Decl(discriminantElementAccessCheck.ts, 6, 17)) + + return val.b; +>val.b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 15, 22)) +>b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) + + } else { + return val.a; +>val.a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 15, 22)) +>a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) + } +} + +function SwitchWithString(val: U) { +>SwitchWithString : Symbol(SwitchWithString, Decl(discriminantElementAccessCheck.ts, 21, 1)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 23, 26)) +>U : Symbol(U, Decl(discriminantElementAccessCheck.ts, 0, 0)) + + switch (val['kind']) { +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 23, 26)) +>'kind' : Symbol(kind, Decl(discriminantElementAccessCheck.ts, 2, 17), Decl(discriminantElementAccessCheck.ts, 6, 17)) + + case 'A': + return val.a; +>val.a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 23, 26)) +>a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) + + case 'B': + return val.b; +>val.b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 23, 26)) +>b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) + + default: + return assertNever(val); +>assertNever : Symbol(assertNever, Decl(discriminantElementAccessCheck.ts, 9, 1)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 23, 26)) + } +} + +function IfWithTemplate(val: U) { +>IfWithTemplate : Symbol(IfWithTemplate, Decl(discriminantElementAccessCheck.ts, 32, 1)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 34, 24)) +>U : Symbol(U, Decl(discriminantElementAccessCheck.ts, 0, 0)) + + if (val[`kind`] === 'B') { +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 34, 24)) +>`kind` : Symbol(kind, Decl(discriminantElementAccessCheck.ts, 2, 17), Decl(discriminantElementAccessCheck.ts, 6, 17)) + + return val.b; +>val.b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 34, 24)) +>b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) + + } else { + return val.a; +>val.a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 34, 24)) +>a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) + } +} + +function SwitchWithTemplate(val: U) { +>SwitchWithTemplate : Symbol(SwitchWithTemplate, Decl(discriminantElementAccessCheck.ts, 40, 1)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 42, 28)) +>U : Symbol(U, Decl(discriminantElementAccessCheck.ts, 0, 0)) + + switch (val[`kind`]) { +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 42, 28)) +>`kind` : Symbol(kind, Decl(discriminantElementAccessCheck.ts, 2, 17), Decl(discriminantElementAccessCheck.ts, 6, 17)) + + case 'A': + return val.a; +>val.a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 42, 28)) +>a : Symbol(TypeA.a, Decl(discriminantElementAccessCheck.ts, 3, 14)) + + case 'B': + return val.b; +>val.b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 42, 28)) +>b : Symbol(TypeB.b, Decl(discriminantElementAccessCheck.ts, 7, 14)) + + default: + return assertNever(val); +>assertNever : Symbol(assertNever, Decl(discriminantElementAccessCheck.ts, 9, 1)) +>val : Symbol(val, Decl(discriminantElementAccessCheck.ts, 42, 28)) + } +} diff --git a/tests/baselines/reference/discriminantElementAccessCheck.types b/tests/baselines/reference/discriminantElementAccessCheck.types new file mode 100644 index 0000000000000..357173b8a0f40 --- /dev/null +++ b/tests/baselines/reference/discriminantElementAccessCheck.types @@ -0,0 +1,140 @@ +=== tests/cases/compiler/discriminantElementAccessCheck.ts === +type U = TypeA | TypeB; +>U : U + +interface TypeA { + kind: 'A'; +>kind : "A" + + a: number; +>a : number +} +interface TypeB { + kind: 'B'; +>kind : "B" + + b: string; +>b : string +} + +function assertNever(x: never) { +>assertNever : (x: never) => never +>x : never + + return x; +>x : never +} + +function IfWithString(val: U) { +>IfWithString : (val: U) => string | number +>val : U + + if (val['kind'] === 'B') { +>val['kind'] === 'B' : boolean +>val['kind'] : "A" | "B" +>val : U +>'kind' : "kind" +>'B' : "B" + + return val.b; +>val.b : string +>val : TypeB +>b : string + + } else { + return val.a; +>val.a : number +>val : TypeA +>a : number + } +} + +function SwitchWithString(val: U) { +>SwitchWithString : (val: U) => string | number +>val : U + + switch (val['kind']) { +>val['kind'] : "A" | "B" +>val : U +>'kind' : "kind" + + case 'A': +>'A' : "A" + + return val.a; +>val.a : number +>val : TypeA +>a : number + + case 'B': +>'B' : "B" + + return val.b; +>val.b : string +>val : TypeB +>b : string + + default: + return assertNever(val); +>assertNever(val) : never +>assertNever : (x: never) => never +>val : never + } +} + +function IfWithTemplate(val: U) { +>IfWithTemplate : (val: U) => string | number +>val : U + + if (val[`kind`] === 'B') { +>val[`kind`] === 'B' : boolean +>val[`kind`] : "A" | "B" +>val : U +>`kind` : "kind" +>'B' : "B" + + return val.b; +>val.b : string +>val : TypeB +>b : string + + } else { + return val.a; +>val.a : number +>val : TypeA +>a : number + } +} + +function SwitchWithTemplate(val: U) { +>SwitchWithTemplate : (val: U) => string | number +>val : U + + switch (val[`kind`]) { +>val[`kind`] : "A" | "B" +>val : U +>`kind` : "kind" + + case 'A': +>'A' : "A" + + return val.a; +>val.a : number +>val : TypeA +>a : number + + case 'B': +>'B' : "B" + + return val.b; +>val.b : string +>val : TypeB +>b : string + + default: + return assertNever(val); +>assertNever(val) : never +>assertNever : (x: never) => never +>val : never + } +} diff --git a/tests/cases/compiler/discriminantElementAccessCheck.ts b/tests/cases/compiler/discriminantElementAccessCheck.ts new file mode 100644 index 0000000000000..ded752f968892 --- /dev/null +++ b/tests/cases/compiler/discriminantElementAccessCheck.ts @@ -0,0 +1,52 @@ +type U = TypeA | TypeB; + +interface TypeA { + kind: 'A'; + a: number; +} +interface TypeB { + kind: 'B'; + b: string; +} + +function assertNever(x: never) { + return x; +} + +function IfWithString(val: U) { + if (val['kind'] === 'B') { + return val.b; + } else { + return val.a; + } +} + +function SwitchWithString(val: U) { + switch (val['kind']) { + case 'A': + return val.a; + case 'B': + return val.b; + default: + return assertNever(val); + } +} + +function IfWithTemplate(val: U) { + if (val[`kind`] === 'B') { + return val.b; + } else { + return val.a; + } +} + +function SwitchWithTemplate(val: U) { + switch (val[`kind`]) { + case 'A': + return val.a; + case 'B': + return val.b; + default: + return assertNever(val); + } +} \ No newline at end of file From 7aa03bf44ee271a71f1774adf2767b2de2b66228 Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Fri, 26 Jul 2019 00:19:36 +0300 Subject: [PATCH 05/10] Support template literals in ambient module declaration --- src/compiler/checker.ts | 2 +- .../ambientModuleWithTemplateLiterals.js | 28 ++++++++ .../ambientModuleWithTemplateLiterals.symbols | 65 +++++++++++++++++ .../ambientModuleWithTemplateLiterals.types | 72 +++++++++++++++++++ .../ambientModuleWithTemplateLiterals.ts | 20 ++++++ 5 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/ambientModuleWithTemplateLiterals.js create mode 100644 tests/baselines/reference/ambientModuleWithTemplateLiterals.symbols create mode 100644 tests/baselines/reference/ambientModuleWithTemplateLiterals.types create mode 100644 tests/cases/compiler/ambientModuleWithTemplateLiterals.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 275ac54088999..8a4ee3d86454a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33702,7 +33702,7 @@ namespace ts { } function isStringOrNumberLiteralExpression(expr: Expression) { - return expr.kind === SyntaxKind.StringLiteral || expr.kind === SyntaxKind.NumericLiteral || + return isStringOrNumericLiteralLike(expr) || expr.kind === SyntaxKind.PrefixUnaryExpression && (expr).operator === SyntaxKind.MinusToken && (expr).operand.kind === SyntaxKind.NumericLiteral; } diff --git a/tests/baselines/reference/ambientModuleWithTemplateLiterals.js b/tests/baselines/reference/ambientModuleWithTemplateLiterals.js new file mode 100644 index 0000000000000..e9c55fe7ca055 --- /dev/null +++ b/tests/baselines/reference/ambientModuleWithTemplateLiterals.js @@ -0,0 +1,28 @@ +//// [ambientModuleWithTemplateLiterals.ts] +declare module Foo { + enum Bar { + a = `1`, + b = '2', + c = '3' + } + + export const a = 'string'; + export const b = `template`; + + export const c = Bar.a; + export const d = Bar['b']; + export const e = Bar[`c`]; +} + +Foo.a; +Foo.b; +Foo.c; +Foo.d; +Foo.e; + +//// [ambientModuleWithTemplateLiterals.js] +Foo.a; +Foo.b; +Foo.c; +Foo.d; +Foo.e; diff --git a/tests/baselines/reference/ambientModuleWithTemplateLiterals.symbols b/tests/baselines/reference/ambientModuleWithTemplateLiterals.symbols new file mode 100644 index 0000000000000..25086b1918e4c --- /dev/null +++ b/tests/baselines/reference/ambientModuleWithTemplateLiterals.symbols @@ -0,0 +1,65 @@ +=== tests/cases/compiler/ambientModuleWithTemplateLiterals.ts === +declare module Foo { +>Foo : Symbol(Foo, Decl(ambientModuleWithTemplateLiterals.ts, 0, 0)) + + enum Bar { +>Bar : Symbol(Bar, Decl(ambientModuleWithTemplateLiterals.ts, 0, 20)) + + a = `1`, +>a : Symbol(Bar.a, Decl(ambientModuleWithTemplateLiterals.ts, 1, 14)) + + b = '2', +>b : Symbol(Bar.b, Decl(ambientModuleWithTemplateLiterals.ts, 2, 16)) + + c = '3' +>c : Symbol(Bar.c, Decl(ambientModuleWithTemplateLiterals.ts, 3, 16)) + } + + export const a = 'string'; +>a : Symbol(a, Decl(ambientModuleWithTemplateLiterals.ts, 7, 16)) + + export const b = `template`; +>b : Symbol(b, Decl(ambientModuleWithTemplateLiterals.ts, 8, 16)) + + export const c = Bar.a; +>c : Symbol(c, Decl(ambientModuleWithTemplateLiterals.ts, 10, 16)) +>Bar.a : Symbol(Bar.a, Decl(ambientModuleWithTemplateLiterals.ts, 1, 14)) +>Bar : Symbol(Bar, Decl(ambientModuleWithTemplateLiterals.ts, 0, 20)) +>a : Symbol(Bar.a, Decl(ambientModuleWithTemplateLiterals.ts, 1, 14)) + + export const d = Bar['b']; +>d : Symbol(d, Decl(ambientModuleWithTemplateLiterals.ts, 11, 16)) +>Bar : Symbol(Bar, Decl(ambientModuleWithTemplateLiterals.ts, 0, 20)) +>'b' : Symbol(Bar.b, Decl(ambientModuleWithTemplateLiterals.ts, 2, 16)) + + export const e = Bar[`c`]; +>e : Symbol(e, Decl(ambientModuleWithTemplateLiterals.ts, 12, 16)) +>Bar : Symbol(Bar, Decl(ambientModuleWithTemplateLiterals.ts, 0, 20)) +>`c` : Symbol(Bar.c, Decl(ambientModuleWithTemplateLiterals.ts, 3, 16)) +} + +Foo.a; +>Foo.a : Symbol(Foo.a, Decl(ambientModuleWithTemplateLiterals.ts, 7, 16)) +>Foo : Symbol(Foo, Decl(ambientModuleWithTemplateLiterals.ts, 0, 0)) +>a : Symbol(Foo.a, Decl(ambientModuleWithTemplateLiterals.ts, 7, 16)) + +Foo.b; +>Foo.b : Symbol(Foo.b, Decl(ambientModuleWithTemplateLiterals.ts, 8, 16)) +>Foo : Symbol(Foo, Decl(ambientModuleWithTemplateLiterals.ts, 0, 0)) +>b : Symbol(Foo.b, Decl(ambientModuleWithTemplateLiterals.ts, 8, 16)) + +Foo.c; +>Foo.c : Symbol(Foo.c, Decl(ambientModuleWithTemplateLiterals.ts, 10, 16)) +>Foo : Symbol(Foo, Decl(ambientModuleWithTemplateLiterals.ts, 0, 0)) +>c : Symbol(Foo.c, Decl(ambientModuleWithTemplateLiterals.ts, 10, 16)) + +Foo.d; +>Foo.d : Symbol(Foo.d, Decl(ambientModuleWithTemplateLiterals.ts, 11, 16)) +>Foo : Symbol(Foo, Decl(ambientModuleWithTemplateLiterals.ts, 0, 0)) +>d : Symbol(Foo.d, Decl(ambientModuleWithTemplateLiterals.ts, 11, 16)) + +Foo.e; +>Foo.e : Symbol(Foo.e, Decl(ambientModuleWithTemplateLiterals.ts, 12, 16)) +>Foo : Symbol(Foo, Decl(ambientModuleWithTemplateLiterals.ts, 0, 0)) +>e : Symbol(Foo.e, Decl(ambientModuleWithTemplateLiterals.ts, 12, 16)) + diff --git a/tests/baselines/reference/ambientModuleWithTemplateLiterals.types b/tests/baselines/reference/ambientModuleWithTemplateLiterals.types new file mode 100644 index 0000000000000..05882261f2d0b --- /dev/null +++ b/tests/baselines/reference/ambientModuleWithTemplateLiterals.types @@ -0,0 +1,72 @@ +=== tests/cases/compiler/ambientModuleWithTemplateLiterals.ts === +declare module Foo { +>Foo : typeof Foo + + enum Bar { +>Bar : Bar + + a = `1`, +>a : Bar.a +>`1` : "1" + + b = '2', +>b : Bar.b +>'2' : "2" + + c = '3' +>c : Bar.c +>'3' : "3" + } + + export const a = 'string'; +>a : "string" +>'string' : "string" + + export const b = `template`; +>b : "template" +>`template` : "template" + + export const c = Bar.a; +>c : Bar.a +>Bar.a : Bar.a +>Bar : typeof Bar +>a : Bar.a + + export const d = Bar['b']; +>d : Bar.b +>Bar['b'] : Bar.b +>Bar : typeof Bar +>'b' : "b" + + export const e = Bar[`c`]; +>e : Bar.c +>Bar[`c`] : Bar.c +>Bar : typeof Bar +>`c` : "c" +} + +Foo.a; +>Foo.a : "string" +>Foo : typeof Foo +>a : "string" + +Foo.b; +>Foo.b : "template" +>Foo : typeof Foo +>b : "template" + +Foo.c; +>Foo.c : Foo.Bar.a +>Foo : typeof Foo +>c : Foo.Bar.a + +Foo.d; +>Foo.d : Foo.Bar.b +>Foo : typeof Foo +>d : Foo.Bar.b + +Foo.e; +>Foo.e : Foo.Bar.c +>Foo : typeof Foo +>e : Foo.Bar.c + diff --git a/tests/cases/compiler/ambientModuleWithTemplateLiterals.ts b/tests/cases/compiler/ambientModuleWithTemplateLiterals.ts new file mode 100644 index 0000000000000..74c1b29e52dce --- /dev/null +++ b/tests/cases/compiler/ambientModuleWithTemplateLiterals.ts @@ -0,0 +1,20 @@ +declare module Foo { + enum Bar { + a = `1`, + b = '2', + c = '3' + } + + export const a = 'string'; + export const b = `template`; + + export const c = Bar.a; + export const d = Bar['b']; + export const e = Bar[`c`]; +} + +Foo.a; +Foo.b; +Foo.c; +Foo.d; +Foo.e; \ No newline at end of file From 0a9f0c70679ceac3f1a70b2a5ae12a1869a5725b Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Mon, 24 Jun 2019 03:11:23 +0300 Subject: [PATCH 06/10] Unify symboles for template literals in computed properties --- src/compiler/utilities.ts | 2 +- tests/baselines/reference/computedPropertyNames10_ES5.symbols | 1 + tests/baselines/reference/computedPropertyNames10_ES6.symbols | 1 + tests/baselines/reference/computedPropertyNames11_ES5.symbols | 1 + tests/baselines/reference/computedPropertyNames11_ES6.symbols | 1 + tests/baselines/reference/computedPropertyNames12_ES5.symbols | 1 + tests/baselines/reference/computedPropertyNames12_ES6.symbols | 1 + tests/baselines/reference/computedPropertyNames13_ES5.symbols | 1 + tests/baselines/reference/computedPropertyNames13_ES6.symbols | 1 + tests/baselines/reference/computedPropertyNames16_ES5.symbols | 1 + tests/baselines/reference/computedPropertyNames16_ES6.symbols | 1 + tests/baselines/reference/computedPropertyNames4_ES5.symbols | 1 + tests/baselines/reference/computedPropertyNames4_ES6.symbols | 1 + .../computerPropertiesInES5ShouldBeTransformed.symbols | 1 + 14 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1645b9339ae5f..a71d5d3a346fa 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2556,7 +2556,7 @@ namespace ts { } export function isLiteralComputedPropertyDeclarationName(node: Node) { - return (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) && + return isStringOrNumericLiteralLike(node) && node.parent.kind === SyntaxKind.ComputedPropertyName && isDeclaration(node.parent.parent); } diff --git a/tests/baselines/reference/computedPropertyNames10_ES5.symbols b/tests/baselines/reference/computedPropertyNames10_ES5.symbols index a63bac47a2858..8a93cbac50846 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES5.symbols +++ b/tests/baselines/reference/computedPropertyNames10_ES5.symbols @@ -50,6 +50,7 @@ var v = { [`hello bye`]() { }, >[`hello bye`] : Symbol([`hello bye`], Decl(computedPropertyNames10_ES5.ts, 12, 22)) +>`hello bye` : Symbol([`hello bye`], Decl(computedPropertyNames10_ES5.ts, 12, 22)) [`hello ${a} bye`]() { } >[`hello ${a} bye`] : Symbol([`hello ${a} bye`], Decl(computedPropertyNames10_ES5.ts, 13, 24)) diff --git a/tests/baselines/reference/computedPropertyNames10_ES6.symbols b/tests/baselines/reference/computedPropertyNames10_ES6.symbols index bbfe8d3808da2..73a97d7c003dd 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES6.symbols +++ b/tests/baselines/reference/computedPropertyNames10_ES6.symbols @@ -50,6 +50,7 @@ var v = { [`hello bye`]() { }, >[`hello bye`] : Symbol([`hello bye`], Decl(computedPropertyNames10_ES6.ts, 12, 22)) +>`hello bye` : Symbol([`hello bye`], Decl(computedPropertyNames10_ES6.ts, 12, 22)) [`hello ${a} bye`]() { } >[`hello ${a} bye`] : Symbol([`hello ${a} bye`], Decl(computedPropertyNames10_ES6.ts, 13, 24)) diff --git a/tests/baselines/reference/computedPropertyNames11_ES5.symbols b/tests/baselines/reference/computedPropertyNames11_ES5.symbols index e1c7d7231f4fa..b030d727921e9 100644 --- a/tests/baselines/reference/computedPropertyNames11_ES5.symbols +++ b/tests/baselines/reference/computedPropertyNames11_ES5.symbols @@ -54,6 +54,7 @@ var v = { set [`hello bye`](v) { }, >[`hello bye`] : Symbol([`hello bye`], Decl(computedPropertyNames11_ES5.ts, 12, 36)) +>`hello bye` : Symbol([`hello bye`], Decl(computedPropertyNames11_ES5.ts, 12, 36)) >v : Symbol(v, Decl(computedPropertyNames11_ES5.ts, 13, 22)) get [`hello ${a} bye`]() { return 0; } diff --git a/tests/baselines/reference/computedPropertyNames11_ES6.symbols b/tests/baselines/reference/computedPropertyNames11_ES6.symbols index fcd142feac68a..04273804fda27 100644 --- a/tests/baselines/reference/computedPropertyNames11_ES6.symbols +++ b/tests/baselines/reference/computedPropertyNames11_ES6.symbols @@ -54,6 +54,7 @@ var v = { set [`hello bye`](v) { }, >[`hello bye`] : Symbol([`hello bye`], Decl(computedPropertyNames11_ES6.ts, 12, 36)) +>`hello bye` : Symbol([`hello bye`], Decl(computedPropertyNames11_ES6.ts, 12, 36)) >v : Symbol(v, Decl(computedPropertyNames11_ES6.ts, 13, 22)) get [`hello ${a} bye`]() { return 0; } diff --git a/tests/baselines/reference/computedPropertyNames12_ES5.symbols b/tests/baselines/reference/computedPropertyNames12_ES5.symbols index 40f5989b9c024..6746b115bedf5 100644 --- a/tests/baselines/reference/computedPropertyNames12_ES5.symbols +++ b/tests/baselines/reference/computedPropertyNames12_ES5.symbols @@ -52,6 +52,7 @@ class C { [`hello bye`] = 0; >[`hello bye`] : Symbol(C[`hello bye`], Decl(computedPropertyNames12_ES5.ts, 12, 31)) +>`hello bye` : Symbol(C[`hello bye`], Decl(computedPropertyNames12_ES5.ts, 12, 31)) static [`hello ${a} bye`] = 0 >[`hello ${a} bye`] : Symbol(C[`hello ${a} bye`], Decl(computedPropertyNames12_ES5.ts, 13, 22)) diff --git a/tests/baselines/reference/computedPropertyNames12_ES6.symbols b/tests/baselines/reference/computedPropertyNames12_ES6.symbols index 9ea89571d8267..8ab0d06f8f9f1 100644 --- a/tests/baselines/reference/computedPropertyNames12_ES6.symbols +++ b/tests/baselines/reference/computedPropertyNames12_ES6.symbols @@ -52,6 +52,7 @@ class C { [`hello bye`] = 0; >[`hello bye`] : Symbol(C[`hello bye`], Decl(computedPropertyNames12_ES6.ts, 12, 31)) +>`hello bye` : Symbol(C[`hello bye`], Decl(computedPropertyNames12_ES6.ts, 12, 31)) static [`hello ${a} bye`] = 0 >[`hello ${a} bye`] : Symbol(C[`hello ${a} bye`], Decl(computedPropertyNames12_ES6.ts, 13, 22)) diff --git a/tests/baselines/reference/computedPropertyNames13_ES5.symbols b/tests/baselines/reference/computedPropertyNames13_ES5.symbols index 4d80f861952ea..7df3db735a9fb 100644 --- a/tests/baselines/reference/computedPropertyNames13_ES5.symbols +++ b/tests/baselines/reference/computedPropertyNames13_ES5.symbols @@ -50,6 +50,7 @@ class C { [`hello bye`]() { } >[`hello bye`] : Symbol(C[`hello bye`], Decl(computedPropertyNames13_ES5.ts, 12, 28)) +>`hello bye` : Symbol(C[`hello bye`], Decl(computedPropertyNames13_ES5.ts, 12, 28)) static [`hello ${a} bye`]() { } >[`hello ${a} bye`] : Symbol(C[`hello ${a} bye`], Decl(computedPropertyNames13_ES5.ts, 13, 23)) diff --git a/tests/baselines/reference/computedPropertyNames13_ES6.symbols b/tests/baselines/reference/computedPropertyNames13_ES6.symbols index 088522617a7ec..5da1dfd1705af 100644 --- a/tests/baselines/reference/computedPropertyNames13_ES6.symbols +++ b/tests/baselines/reference/computedPropertyNames13_ES6.symbols @@ -50,6 +50,7 @@ class C { [`hello bye`]() { } >[`hello bye`] : Symbol(C[`hello bye`], Decl(computedPropertyNames13_ES6.ts, 12, 28)) +>`hello bye` : Symbol(C[`hello bye`], Decl(computedPropertyNames13_ES6.ts, 12, 28)) static [`hello ${a} bye`]() { } >[`hello ${a} bye`] : Symbol(C[`hello ${a} bye`], Decl(computedPropertyNames13_ES6.ts, 13, 23)) diff --git a/tests/baselines/reference/computedPropertyNames16_ES5.symbols b/tests/baselines/reference/computedPropertyNames16_ES5.symbols index 1099ece10012a..ffd0c0594a820 100644 --- a/tests/baselines/reference/computedPropertyNames16_ES5.symbols +++ b/tests/baselines/reference/computedPropertyNames16_ES5.symbols @@ -54,6 +54,7 @@ class C { set [`hello bye`](v) { } >[`hello bye`] : Symbol(C[`hello bye`], Decl(computedPropertyNames16_ES5.ts, 12, 42)) +>`hello bye` : Symbol(C[`hello bye`], Decl(computedPropertyNames16_ES5.ts, 12, 42)) >v : Symbol(v, Decl(computedPropertyNames16_ES5.ts, 13, 22)) get [`hello ${a} bye`]() { return 0; } diff --git a/tests/baselines/reference/computedPropertyNames16_ES6.symbols b/tests/baselines/reference/computedPropertyNames16_ES6.symbols index 11511eb577460..09e585e3b98c7 100644 --- a/tests/baselines/reference/computedPropertyNames16_ES6.symbols +++ b/tests/baselines/reference/computedPropertyNames16_ES6.symbols @@ -54,6 +54,7 @@ class C { set [`hello bye`](v) { } >[`hello bye`] : Symbol(C[`hello bye`], Decl(computedPropertyNames16_ES6.ts, 12, 42)) +>`hello bye` : Symbol(C[`hello bye`], Decl(computedPropertyNames16_ES6.ts, 12, 42)) >v : Symbol(v, Decl(computedPropertyNames16_ES6.ts, 13, 22)) get [`hello ${a} bye`]() { return 0; } diff --git a/tests/baselines/reference/computedPropertyNames4_ES5.symbols b/tests/baselines/reference/computedPropertyNames4_ES5.symbols index ccb9481831047..e321bf2e956ee 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES5.symbols +++ b/tests/baselines/reference/computedPropertyNames4_ES5.symbols @@ -52,6 +52,7 @@ var v = { [`hello bye`]: 0, >[`hello bye`] : Symbol([`hello bye`], Decl(computedPropertyNames4_ES5.ts, 12, 19)) +>`hello bye` : Symbol([`hello bye`], Decl(computedPropertyNames4_ES5.ts, 12, 19)) [`hello ${a} bye`]: 0 >[`hello ${a} bye`] : Symbol([`hello ${a} bye`], Decl(computedPropertyNames4_ES5.ts, 13, 21)) diff --git a/tests/baselines/reference/computedPropertyNames4_ES6.symbols b/tests/baselines/reference/computedPropertyNames4_ES6.symbols index aeb3e59789780..542e75218735d 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES6.symbols +++ b/tests/baselines/reference/computedPropertyNames4_ES6.symbols @@ -52,6 +52,7 @@ var v = { [`hello bye`]: 0, >[`hello bye`] : Symbol([`hello bye`], Decl(computedPropertyNames4_ES6.ts, 12, 19)) +>`hello bye` : Symbol([`hello bye`], Decl(computedPropertyNames4_ES6.ts, 12, 19)) [`hello ${a} bye`]: 0 >[`hello ${a} bye`] : Symbol([`hello ${a} bye`], Decl(computedPropertyNames4_ES6.ts, 13, 21)) diff --git a/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.symbols b/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.symbols index c118c1d0eff73..3ca78b256c575 100644 --- a/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.symbols +++ b/tests/baselines/reference/computerPropertiesInES5ShouldBeTransformed.symbols @@ -1,6 +1,7 @@ === tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts === const b = ({ [`key`]: renamed }) => renamed; >b : Symbol(b, Decl(computerPropertiesInES5ShouldBeTransformed.ts, 0, 5)) +>`key` : Symbol(renamed, Decl(computerPropertiesInES5ShouldBeTransformed.ts, 0, 12)) >renamed : Symbol(renamed, Decl(computerPropertiesInES5ShouldBeTransformed.ts, 0, 12)) >renamed : Symbol(renamed, Decl(computerPropertiesInES5ShouldBeTransformed.ts, 0, 12)) From c6046766423ecad30e24ba0c74563505f46e1330 Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Mon, 24 Jun 2019 04:51:16 +0300 Subject: [PATCH 07/10] Unify expression position checks for template literals --- src/compiler/utilities.ts | 2 +- .../reference/noSubstitutionTemplateStringLiteralTypes.types | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a71d5d3a346fa..f4544325ddd2a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1692,7 +1692,6 @@ namespace ts { case SyntaxKind.ConditionalExpression: case SyntaxKind.SpreadElement: case SyntaxKind.TemplateExpression: - case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.OmittedExpression: case SyntaxKind.JsxElement: case SyntaxKind.JsxSelfClosingElement: @@ -1715,6 +1714,7 @@ namespace ts { case SyntaxKind.NumericLiteral: case SyntaxKind.BigIntLiteral: case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.ThisKeyword: return isInExpressionContext(node); default: diff --git a/tests/baselines/reference/noSubstitutionTemplateStringLiteralTypes.types b/tests/baselines/reference/noSubstitutionTemplateStringLiteralTypes.types index 2274e703ddcc1..945dee6a4d119 100644 --- a/tests/baselines/reference/noSubstitutionTemplateStringLiteralTypes.types +++ b/tests/baselines/reference/noSubstitutionTemplateStringLiteralTypes.types @@ -1,6 +1,5 @@ === tests/cases/compiler/noSubstitutionTemplateStringLiteralTypes.ts === const x: `foo` = "foo"; >x : "foo" ->`foo` : "foo" >"foo" : "foo" From 2b93227667ab9966abcd528ef14a589d80ddb9ba Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Wed, 18 Sep 2019 01:34:31 +0300 Subject: [PATCH 08/10] Support template literals in rename and find all references --- src/compiler/utilities.ts | 10 ++++- src/services/findAllReferences.ts | 5 ++- src/services/rename.ts | 3 +- src/services/services.ts | 1 + src/services/utilities.ts | 2 +- ...enameTemplateLiteralsComputedProperties.ts | 42 +++++++++++++++++++ .../renameTemplateLiteralsDefinePropertyJs.ts | 18 ++++++++ 7 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 tests/cases/fourslash/renameTemplateLiteralsComputedProperties.ts create mode 100644 tests/cases/fourslash/renameTemplateLiteralsDefinePropertyJs.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f4544325ddd2a..6bbe0cc76aa8c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3220,18 +3220,24 @@ namespace ts { } /** - * Strip off existed single quotes or double quotes from a given string + * Strip off existed surrounding single quotes, double quotes, or backticks from a given string * * @return non-quoted string */ export function stripQuotes(name: string) { const length = name.length; - if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && startsWithQuote(name)) { + if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && isQuoteOrBacktick(name.charCodeAt(0))) { return name.substring(1, length - 1); } return name; } + function isQuoteOrBacktick(charCode: number) { + return charCode === CharacterCodes.singleQuote || + charCode === CharacterCodes.doubleQuote || + charCode === CharacterCodes.backtick; + } + export function startsWithQuote(name: string): boolean { return isSingleOrDoubleQuote(name.charCodeAt(0)); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index f98fb2f75b8d8..143a2a4c5da2b 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -448,7 +448,7 @@ namespace ts.FindAllReferences { function getTextSpan(node: Node, sourceFile: SourceFile, endNode?: Node): TextSpan { let start = node.getStart(sourceFile); let end = (endNode || node).getEnd(); - if (node.kind === SyntaxKind.StringLiteral) { + if (isStringLiteralLike(node)) { Debug.assert(endNode === undefined); start += 1; end -= 1; @@ -1234,8 +1234,9 @@ namespace ts.FindAllReferences.Core { case SyntaxKind.Identifier: return (node as Identifier).text.length === searchSymbolName.length; + case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.StringLiteral: { - const str = node as StringLiteral; + const str = node as StringLiteralLike; return (isLiteralNameOfPropertyDeclarationOrIndexAccess(str) || isNameOfModuleDeclaration(node) || isExpressionOfExternalModuleImportEqualsDeclaration(node) || (isCallExpression(node.parent) && isBindableObjectDefinePropertyCall(node.parent) && node.parent.arguments[1] === node)) && str.text.length === searchSymbolName.length; } diff --git a/src/services/rename.ts b/src/services/rename.ts index 484349acc8683..775051a8364c3 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -81,7 +81,7 @@ namespace ts.Rename { function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) { let start = node.getStart(sourceFile); let width = node.getWidth(sourceFile); - if (node.kind === SyntaxKind.StringLiteral) { + if (isStringLiteralLike(node)) { // Exclude the quotes start += 1; width -= 2; @@ -93,6 +93,7 @@ namespace ts.Rename { switch (node.kind) { case SyntaxKind.Identifier: case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.ThisKeyword: return true; case SyntaxKind.NumericLiteral: diff --git a/src/services/services.ts b/src/services/services.ts index 644629ce2af4f..7a51cc36b9425 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2227,6 +2227,7 @@ namespace ts { function getContainingObjectLiteralElementWorker(node: Node): ObjectLiteralElement | undefined { switch (node.kind) { case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.NumericLiteral: if (node.parent.kind === SyntaxKind.ComputedPropertyName) { return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 91b0a7a19914b..934eb8f4f4624 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -267,7 +267,7 @@ namespace ts { isFunctionLike(node.parent) && (node.parent).name === node; } - export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral): boolean { + export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral | NoSubstitutionTemplateLiteral): boolean { switch (node.parent.kind) { case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: diff --git a/tests/cases/fourslash/renameTemplateLiteralsComputedProperties.ts b/tests/cases/fourslash/renameTemplateLiteralsComputedProperties.ts new file mode 100644 index 0000000000000..f6353d1a3d7ac --- /dev/null +++ b/tests/cases/fourslash/renameTemplateLiteralsComputedProperties.ts @@ -0,0 +1,42 @@ +/// + +// @Filename: a.ts +////interface Obj { +//// [|[`[|{| "contextRangeIndex": 0 |}num|]`]: number;|] +//// [|['[|{| "contextRangeIndex": 2 |}bool|]']: boolean;|] +////} +//// +////let o: Obj = { +//// [|[`[|{| "contextRangeIndex": 4 |}num|]`]: 0|], +//// [|['[|{| "contextRangeIndex": 6 |}bool|]']: true|], +////}; +//// +////o = { +//// [|['[|{| "contextRangeIndex": 8 |}num|]']: 1|], +//// [|[`[|{| "contextRangeIndex": 10 |}bool|]`]: false|], +////}; +//// +////o.[|num|]; +////o['[|num|]']; +////o["[|num|]"]; +////o[`[|num|]`]; +//// +////o.[|bool|]; +////o['[|bool|]']; +////o["[|bool|]"]; +////o[`[|bool|]`]; +//// +////export { o }; + +// @allowJs: true +// @Filename: b.js +////import { o as obj } from './a'; +//// +////obj.[|num|]; +////obj[`[|num|]`]; +//// +////obj.[|bool|]; +////obj[`[|bool|]`]; + +verify.rangesWithSameTextAreRenameLocations("num"); +verify.rangesWithSameTextAreRenameLocations("bool"); diff --git a/tests/cases/fourslash/renameTemplateLiteralsDefinePropertyJs.ts b/tests/cases/fourslash/renameTemplateLiteralsDefinePropertyJs.ts new file mode 100644 index 0000000000000..ade3a8bf0be60 --- /dev/null +++ b/tests/cases/fourslash/renameTemplateLiteralsDefinePropertyJs.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true +// @Filename: a.js +////let obj = {}; +//// +////Object.defineProperty(obj, `[|prop|]`, { value: 0 }); +//// +////obj = { +//// [|[`[|{| "contextRangeIndex": 1 |}prop|]`]: 1|] +////}; +//// +////obj.[|prop|]; +////obj['[|prop|]']; +////obj["[|prop|]"]; +////obj[`[|prop|]`]; + +verify.rangesWithSameTextAreRenameLocations('prop'); From cc8a514f0b95e6019a9af9a00063a3d8f3f52b48 Mon Sep 17 00:00:00 2001 From: IllusionMH Date: Tue, 24 Sep 2019 05:10:43 +0300 Subject: [PATCH 09/10] Mark computed properties with template literals as write access --- src/compiler/utilities.ts | 1 + .../cases/fourslash/findAllRefsWriteAccess.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 tests/cases/fourslash/findAllRefsWriteAccess.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6bbe0cc76aa8c..3283ae916f4c7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2529,6 +2529,7 @@ namespace ts { const parent = name.parent; switch (name.kind) { case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.NumericLiteral: if (isComputedPropertyName(parent)) return parent.parent; // falls through diff --git a/tests/cases/fourslash/findAllRefsWriteAccess.ts b/tests/cases/fourslash/findAllRefsWriteAccess.ts new file mode 100644 index 0000000000000..550938a7c0f55 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsWriteAccess.ts @@ -0,0 +1,21 @@ +/// + +////interface Obj { +//// [|[`[|{| "isDefinition": true, "contextRangeIndex": 0 |}num|]`]: number;|] +////} +//// +////let o: Obj = { +//// [|[`[|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 2 |}num|]`]: 0|] +////}; +//// +////o = { +//// [|['[|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 4 |}num|]']: 1|] +////}; +//// +////o['[|num|]'] = 2; +////o[`[|num|]`] = 3; +//// +////o['[|num|]']; +////o[`[|num|]`]; + +verify.singleReferenceGroup("(property) Obj[`num`]: number", "num"); From 8db828160bd0e6117718a4f8c8f4ccbe1b99118d Mon Sep 17 00:00:00 2001 From: typescript-bot Date: Thu, 26 Sep 2019 17:10:17 +0000 Subject: [PATCH 10/10] Update user baselines --- .../reference/docker/office-ui-fabric.log | 24 ++--- tests/baselines/reference/user/assert.log | 40 ++++---- tests/baselines/reference/user/axios-src.log | 20 ++-- .../user/chrome-devtools-frontend.log | 91 ++++++++----------- tests/baselines/reference/user/prettier.log | 75 ++++++++------- 5 files changed, 112 insertions(+), 138 deletions(-) diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index 9cda725e39e60..0b8c8e04b1357 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -1,14 +1,5 @@ Exit Code: 1 Standard output: -@uifabric/codepen-loader: yarn run vX.X.X -@uifabric/codepen-loader: $ just-scripts build --production --lint -@uifabric/codepen-loader: [XX:XX:XX XM] ■ Removing [lib, temp, dist, coverage, lib-commonjs] -@uifabric/codepen-loader: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/codepen-loader/tsconfig.json -@uifabric/codepen-loader: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --module commonjs --outDir "./lib" --project "/office-ui-fabric-react/packages/codepen-loader/tsconfig.json" -@uifabric/codepen-loader: [XX:XX:XX XM] ■ Running Jest -@uifabric/codepen-loader: [XX:XX:XX XM] ■ /usr/local/bin/node "/office-ui-fabric-react/node_modules/jest/bin/jest.js" --config "/office-ui-fabric-react/packages/codepen-loader/jest.config.js" --passWithNoTests --colors --forceExit -@uifabric/codepen-loader: PASS src/__tests__/codepenTransform.test.ts -@uifabric/codepen-loader: Done in ?s. @uifabric/build: yarn run vX.X.X @uifabric/build: $ node ./just-scripts.js no-op --production --lint @uifabric/build: Done in ?s. @@ -36,9 +27,11 @@ Standard output: @uifabric/migration: Done in ?s. @uifabric/monaco-editor: yarn run vX.X.X @uifabric/monaco-editor: $ just-scripts build --production --lint -@uifabric/monaco-editor: [XX:XX:XX XM] ■ Removing [esm, lib] +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Removing [esm, lib, lib-commonjs] @uifabric/monaco-editor: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/monaco-editor/tsconfig.json @uifabric/monaco-editor: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib --module esnext --project "/office-ui-fabric-react/packages/monaco-editor/tsconfig.json" +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/monaco-editor/tsconfig.json +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib-commonjs --module commonjs --project "/office-ui-fabric-react/packages/monaco-editor/tsconfig.json" @uifabric/monaco-editor: Done in ?s. @uifabric/set-version: yarn run vX.X.X @uifabric/set-version: $ just-scripts build --production --lint @@ -84,12 +77,14 @@ Standard output: @uifabric/merge-styles: PASS src/mergeStyles.test.ts @uifabric/merge-styles: PASS src/concatStyleSets.test.ts @uifabric/merge-styles: PASS src/transforms/rtlifyRules.test.ts +@uifabric/merge-styles: PASS src/mergeCssSets.test.ts @uifabric/merge-styles: PASS src/transforms/prefixRules.test.ts @uifabric/merge-styles: PASS src/transforms/provideUnits.test.ts @uifabric/merge-styles: PASS src/keyframes.test.ts +@uifabric/merge-styles: PASS src/mergeCss.test.ts +@uifabric/merge-styles: PASS src/server.test.ts @uifabric/merge-styles: PASS src/Stylesheet.test.ts @uifabric/merge-styles: PASS src/extractStyleParts.test.ts -@uifabric/merge-styles: PASS src/server.test.ts @uifabric/merge-styles: PASS src/concatStyleSetsWithProps.test.ts @uifabric/merge-styles: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/merge-styles/lib/index.d.ts' @uifabric/merge-styles: Done in ?s. @@ -206,7 +201,6 @@ Standard output: @uifabric/styling: PASS src/styles/theme.test.ts @uifabric/styling: PASS src/styles/scheme.test.ts @uifabric/styling: PASS src/styles/getGlobalClassNames.test.ts -@uifabric/styling: PASS src/utilities/icons.test.ts @uifabric/styling: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/styling/lib/index.d.ts' @uifabric/styling: Done in ?s. @uifabric/file-type-icons: yarn run vX.X.X @@ -249,11 +243,7 @@ Standard output: Standard error: info cli using local version of lerna lerna notice cli vX.X.X -lerna info Executing command in 43 packages: "yarn run build --production --lint" -@uifabric/codepen-loader: ts-jest[versions] (WARN) Version X.X.X-insiders.xxxxxxxx of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=2.7.0 <4.0.0). Please do not report issues in ts-jest if you are using unsupported versions. -@uifabric/codepen-loader: Force exiting Jest -@uifabric/codepen-loader: -@uifabric/codepen-loader: Have you considered using `--detectOpenHandles` to detect async operations that kept running after all tests finished? +lerna info Executing command in 42 packages: "yarn run build --production --lint" @uifabric/example-data: [XX:XX:XX XM] ▲ One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect @uifabric/set-version: [XX:XX:XX XM] ▲ One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect @uifabric/merge-styles: [XX:XX:XX XM] ▲ One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect diff --git a/tests/baselines/reference/user/assert.log b/tests/baselines/reference/user/assert.log index 4b00cccc6ab64..ce8e6cc19d06e 100644 --- a/tests/baselines/reference/user/assert.log +++ b/tests/baselines/reference/user/assert.log @@ -1,34 +1,34 @@ Exit Code: 1 Standard output: node_modules/assert/test.js(25,5): error TS2367: This condition will always return 'false' since the types 'string | undefined' and 'boolean' have no overlap. -node_modules/assert/test.js(39,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(55,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(74,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(84,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(94,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(103,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(120,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(128,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(39,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(55,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(74,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(84,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(94,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(103,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(120,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(128,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. node_modules/assert/test.js(140,10): error TS2339: Property 'a' does not exist on type 'number[]'. node_modules/assert/test.js(141,10): error TS2339: Property 'b' does not exist on type 'number[]'. node_modules/assert/test.js(142,10): error TS2339: Property 'b' does not exist on type 'number[]'. node_modules/assert/test.js(143,10): error TS2339: Property 'a' does not exist on type 'number[]'. -node_modules/assert/test.js(149,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(149,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. node_modules/assert/test.js(157,51): error TS2349: This expression is not callable. Type 'never' has no call signatures. -node_modules/assert/test.js(161,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(161,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. node_modules/assert/test.js(168,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(182,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(229,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(235,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(250,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(254,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(182,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(229,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(235,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(250,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(254,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? node_modules/assert/test.js(256,55): error TS2345: Argument of type 'TypeError' is not assignable to parameter of type 'string'. -node_modules/assert/test.js(262,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(279,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(285,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(320,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(346,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(262,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(279,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(285,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(320,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(346,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? diff --git a/tests/baselines/reference/user/axios-src.log b/tests/baselines/reference/user/axios-src.log index d24af763712cc..b42bc15b48807 100644 --- a/tests/baselines/reference/user/axios-src.log +++ b/tests/baselines/reference/user/axios-src.log @@ -3,16 +3,16 @@ Standard output: lib/adapters/http.js(13,19): error TS2732: Cannot find module './../../package.json'. Consider using '--resolveJsonModule' to import module with '.json' extension lib/adapters/http.js(84,22): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'. -lib/adapters/http.js(120,17): error TS2532: Object is possibly 'undefined'. -lib/adapters/http.js(120,40): error TS2532: Object is possibly 'undefined'. -lib/adapters/http.js(121,17): error TS2531: Object is possibly 'null'. -lib/adapters/http.js(121,54): error TS2531: Object is possibly 'null'. -lib/adapters/http.js(121,54): error TS2532: Object is possibly 'undefined'. -lib/adapters/http.js(220,23): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. -lib/adapters/http.js(226,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. -lib/adapters/http.js(232,13): error TS2322: Type 'string' is not assignable to type 'Buffer'. -lib/adapters/http.js(244,40): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. -lib/adapters/http.js(273,42): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(124,17): error TS2532: Object is possibly 'undefined'. +lib/adapters/http.js(124,40): error TS2532: Object is possibly 'undefined'. +lib/adapters/http.js(125,17): error TS2531: Object is possibly 'null'. +lib/adapters/http.js(125,54): error TS2531: Object is possibly 'null'. +lib/adapters/http.js(125,54): error TS2532: Object is possibly 'undefined'. +lib/adapters/http.js(224,23): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(230,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(236,13): error TS2322: Type 'string' is not assignable to type 'Buffer'. +lib/adapters/http.js(248,40): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(277,42): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. lib/adapters/xhr.js(64,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. lib/adapters/xhr.js(76,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. lib/adapters/xhr.js(83,51): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. diff --git a/tests/baselines/reference/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index bad901d3d5745..c9ce3bc730bb2 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -3990,10 +3990,9 @@ node_modules/chrome-devtools-frontend/front_end/console/ConsoleView.js(1277,60): node_modules/chrome-devtools-frontend/front_end/console/ConsoleView.js(1278,42): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>[]): { key: string; text: string; regex: RegExp; negative: boolean; }[]', gave the following error. Argument of type '{ key: any; text: string; negative: boolean; }[]' is not assignable to parameter of type 'ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>'. - Types of property 'slice' are incompatible. - Type '(start?: number, end?: number) => { key: any; text: string; negative: boolean; }[]' is not assignable to type '(start?: number, end?: number) => { key: string; text: string; regex: RegExp; negative: boolean; }[]'. - Type '{ key: any; text: string; negative: boolean; }[]' is not assignable to type '{ key: string; text: string; regex: RegExp; negative: boolean; }[]'. - Property 'regex' is missing in type '{ key: any; text: string; negative: boolean; }' but required in type '{ key: string; text: string; regex: RegExp; negative: boolean; }'. + The types returned by 'slice(...)' are incompatible between these types. + Type '{ key: any; text: string; negative: boolean; }[]' is not assignable to type '{ key: string; text: string; regex: RegExp; negative: boolean; }[]'. + Property 'regex' is missing in type '{ key: any; text: string; negative: boolean; }' but required in type '{ key: string; text: string; regex: RegExp; negative: boolean; }'. Overload 2 of 2, '(...items: ({ key: string; text: string; regex: RegExp; negative: boolean; } | ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>)[]): { key: string; text: string; regex: RegExp; negative: boolean; }[]', gave the following error. Argument of type '{ key: any; text: string; negative: boolean; }[]' is not assignable to parameter of type '{ key: string; text: string; regex: RegExp; negative: boolean; } | ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>'. Type '{ key: any; text: string; negative: boolean; }[]' is not assignable to type 'ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>'. @@ -5038,22 +5037,18 @@ node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js( node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js(91,24): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(Promise | Promise)[]' is not assignable to parameter of type 'Iterable>'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator | Promise>' is not assignable to type '() => Iterator, any, undefined>'. - Type 'IterableIterator | Promise>' is not assignable to type 'Iterator, any, undefined>'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult | Promise, any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult, any>'. - Type 'IteratorResult | Promise, any>' is not assignable to type 'IteratorResult, any>'. - Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorResult, any>'. - Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorYieldResult>'. - Type 'Promise | Promise' is not assignable to type 'CSSMatchedStyles | PromiseLike'. - Type 'Promise' is not assignable to type 'CSSMatchedStyles | PromiseLike'. - Type 'Promise' is not assignable to type 'PromiseLike'. - Types of property 'then' are incompatible. - Type '(onfulfilled?: (value: ComputedStyle) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise' is not assignable to type '(onfulfilled?: (value: CSSMatchedStyles) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike<...>'. - Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. - Types of parameters 'value' and 'value' are incompatible. - Type 'ComputedStyle' is missing the following properties from type 'CSSMatchedStyles': _cssModel, _node, _nodeStyles, _nodeForStyle, and 22 more. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult | Promise, any>' is not assignable to type 'IteratorResult, any>'. + Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorResult, any>'. + Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorYieldResult>'. + Type 'Promise | Promise' is not assignable to type 'CSSMatchedStyles | PromiseLike'. + Type 'Promise' is not assignable to type 'CSSMatchedStyles | PromiseLike'. + Type 'Promise' is not assignable to type 'PromiseLike'. + Types of property 'then' are incompatible. + Type '(onfulfilled?: (value: ComputedStyle) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise' is not assignable to type '(onfulfilled?: (value: CSSMatchedStyles) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike<...>'. + Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. + Types of parameters 'value' and 'value' are incompatible. + Type 'ComputedStyle' is missing the following properties from type 'CSSMatchedStyles': _cssModel, _node, _nodeStyles, _nodeForStyle, and 22 more. node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js(147,52): error TS2339: Property 'keysArray' does not exist on type 'Map'. node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js(179,50): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js(200,74): error TS2339: Property 'consume' does not exist on type 'Event'. @@ -5339,22 +5334,18 @@ node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(5 node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(82,24): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(Promise> | Promise)[]' is not assignable to parameter of type 'Iterable | PromiseLike>>'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator> | Promise>' is not assignable to type '() => Iterator | PromiseLike>, any, undefined>'. - Type 'IterableIterator> | Promise>' is not assignable to type 'Iterator | PromiseLike>, any, undefined>'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult> | Promise, any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult | PromiseLike>, any>'. - Type 'IteratorResult> | Promise, any>' is not assignable to type 'IteratorResult | PromiseLike>, any>'. - Type 'IteratorYieldResult> | Promise>' is not assignable to type 'IteratorResult | PromiseLike>, any>'. - Type 'IteratorYieldResult> | Promise>' is not assignable to type 'IteratorYieldResult | PromiseLike>>'. - Type 'Promise> | Promise' is not assignable to type 'Map | PromiseLike>'. - Type 'Promise' is not assignable to type 'Map | PromiseLike>'. - Type 'Promise' is not assignable to type 'PromiseLike>'. - Types of property 'then' are incompatible. - Type '(onfulfilled?: (value: InlineStyleResult) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise<...>' is not assignable to type ', TResult2 = never>(onfulfilled?: (value: Map) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike<...>'. - Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. - Types of parameters 'value' and 'value' are incompatible. - Type 'InlineStyleResult' is missing the following properties from type 'Map': clear, delete, forEach, get, and 8 more. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult> | Promise, any>' is not assignable to type 'IteratorResult | PromiseLike>, any>'. + Type 'IteratorYieldResult> | Promise>' is not assignable to type 'IteratorResult | PromiseLike>, any>'. + Type 'IteratorYieldResult> | Promise>' is not assignable to type 'IteratorYieldResult | PromiseLike>>'. + Type 'Promise> | Promise' is not assignable to type 'Map | PromiseLike>'. + Type 'Promise' is not assignable to type 'Map | PromiseLike>'. + Type 'Promise' is not assignable to type 'PromiseLike>'. + Types of property 'then' are incompatible. + Type '(onfulfilled?: (value: InlineStyleResult) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise<...>' is not assignable to type ', TResult2 = never>(onfulfilled?: (value: Map) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike<...>'. + Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. + Types of parameters 'value' and 'value' are incompatible. + Type 'InlineStyleResult' is missing the following properties from type 'Map': clear, delete, forEach, get, and 8 more. node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(120,11): error TS2339: Property 'consume' does not exist on type 'Event'. node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(164,22): error TS2339: Property 'toFixedIfFloating' does not exist on type 'NumberConstructor'. node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(179,18): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. @@ -12648,22 +12639,18 @@ node_modules/chrome-devtools-frontend/front_end/ui/View.js(454,38): error TS2339 node_modules/chrome-devtools-frontend/front_end/ui/View.js(461,44): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(Promise | Promise)[]' is not assignable to parameter of type 'Iterable>'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator | Promise>' is not assignable to type '() => Iterator, any, undefined>'. - Type 'IterableIterator | Promise>' is not assignable to type 'Iterator, any, undefined>'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult | Promise, any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult, any>'. - Type 'IteratorResult | Promise, any>' is not assignable to type 'IteratorResult, any>'. - Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorResult, any>'. - Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorYieldResult>'. - Type 'Promise | Promise' is not assignable to type 'void | PromiseLike'. - Type 'Promise' is not assignable to type 'void | PromiseLike'. - Type 'Promise' is not assignable to type 'PromiseLike'. - Types of property 'then' are incompatible. - Type '(onfulfilled?: (value: ToolbarItem[]) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise' is not assignable to type '(onfulfilled?: (value: void) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. - Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. - Types of parameters 'value' and 'value' are incompatible. - Type 'ToolbarItem[]' is not assignable to type 'void'. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult | Promise, any>' is not assignable to type 'IteratorResult, any>'. + Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorResult, any>'. + Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorYieldResult>'. + Type 'Promise | Promise' is not assignable to type 'void | PromiseLike'. + Type 'Promise' is not assignable to type 'void | PromiseLike'. + Type 'Promise' is not assignable to type 'PromiseLike'. + Types of property 'then' are incompatible. + Type '(onfulfilled?: (value: ToolbarItem[]) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise' is not assignable to type '(onfulfilled?: (value: void) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. + Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. + Types of parameters 'value' and 'value' are incompatible. + Type 'ToolbarItem[]' is not assignable to type 'void'. node_modules/chrome-devtools-frontend/front_end/ui/View.js(495,24): error TS2339: Property 'createTextChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/ui/View.js(496,24): error TS2339: Property 'tabIndex' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/ui/View.js(501,25): error TS2339: Property 'createChild' does not exist on type 'Element'. diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log index 635c0bc0b3680..6d7d08f01e439 100644 --- a/tests/baselines/reference/user/prettier.log +++ b/tests/baselines/reference/user/prettier.log @@ -142,10 +142,9 @@ src/language-html/printer-html.js(314,13): error TS2769: No overload matches thi src/language-html/printer-html.js(471,11): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type '{ type: string; parts: any; }[]' is not assignable to parameter of type 'ConcatArray'. - Types of property 'slice' are incompatible. - Type '(start?: number | undefined, end?: number | undefined) => { type: string; parts: any; }[]' is not assignable to type '(start?: number | undefined, end?: number | undefined) => never[]'. - Type '{ type: string; parts: any; }[]' is not assignable to type 'never[]'. - Type '{ type: string; parts: any; }' is not assignable to type 'never'. + The types returned by 'slice(...)' are incompatible between these types. + Type '{ type: string; parts: any; }[]' is not assignable to type 'never[]'. + Type '{ type: string; parts: any; }' is not assignable to type 'never'. Overload 2 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type '{ type: string; parts: any; }[]' is not assignable to parameter of type 'ConcatArray'. src/language-html/printer-html.js(492,11): error TS2769: No overload matches this call. @@ -200,11 +199,10 @@ src/language-js/index.js(81,60): error TS2345: Argument of type '{ override: { s src/language-js/needs-parens.js(871,14): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<(childPath: any) => any>[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type 'ConcatArray<(childPath: any) => any>'. - Types of property 'slice' are incompatible. - Type '(start?: number | undefined, end?: number | undefined) => (string | number)[]' is not assignable to type '(start?: number | undefined, end?: number | undefined) => ((childPath: any) => any)[]'. - Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. - Type 'string | number' is not assignable to type '(childPath: any) => any'. - Type 'string' is not assignable to type '(childPath: any) => any'. + The types returned by 'slice(...)' are incompatible between these types. + Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. + Type 'string | number' is not assignable to type '(childPath: any) => any'. + Type 'string' is not assignable to type '(childPath: any) => any'. Overload 2 of 2, '(...items: (((childPath: any) => any) | ConcatArray<(childPath: any) => any>)[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type '((childPath: any) => any) | ConcatArray<(childPath: any) => any>'. Type '(string | number)[]' is not assignable to type 'ConcatArray<(childPath: any) => any>'. @@ -219,56 +217,55 @@ src/language-js/printer-estree.js(400,9): error TS2769: No overload matches this Overload 2 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type '{ type: string; parts: any; } | { type: string; contents: any; n: any; }' is not assignable to parameter of type 'ConcatArray'. Type '{ type: string; parts: any; }' is not assignable to type 'ConcatArray'. -src/language-js/printer-estree.js(1480,28): error TS2769: No overload matches this call. +src/language-js/printer-estree.js(1481,28): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): (string | { type: string; id: any; contents: any; break: boolean; expandedStates: any; })[]', gave the following error. Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'ConcatArray'. Type '{ type: string; parts: any; }' is missing the following properties from type 'ConcatArray': length, join, slice Overload 2 of 2, '(...items: (string | { type: string; id: any; contents: any; break: boolean; expandedStates: any; } | ConcatArray)[]): (string | { ...; })[]', gave the following error. Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string | { type: string; id: any; contents: any; break: boolean; expandedStates: any; } | ConcatArray'. Type '{ type: string; parts: any; }' is missing the following properties from type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }': id, contents, break, expandedStates -src/language-js/printer-estree.js(1913,20): error TS2345: Argument of type '" "' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. -src/language-js/printer-estree.js(1915,20): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. -src/language-js/printer-estree.js(1917,18): error TS2345: Argument of type '"while ("' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. -src/language-js/printer-estree.js(1926,9): error TS2345: Argument of type '")"' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. -src/language-js/printer-estree.js(3472,11): error TS2769: No overload matches this call. +src/language-js/printer-estree.js(1914,20): error TS2345: Argument of type '" "' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(1916,20): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(1918,18): error TS2345: Argument of type '"while ("' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(1927,9): error TS2345: Argument of type '")"' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(3473,11): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type 'never[] | { type: string; parts: any; }' is not assignable to parameter of type 'ConcatArray'. Type '{ type: string; parts: any; }' is not assignable to type 'ConcatArray'. Overload 2 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type 'never[] | { type: string; parts: any; }' is not assignable to parameter of type 'ConcatArray'. Type '{ type: string; parts: any; }' is not assignable to type 'ConcatArray'. -src/language-js/printer-estree.js(3901,22): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. -src/language-js/printer-estree.js(3968,14): error TS2339: Property 'comments' does not exist on type 'Expression'. +src/language-js/printer-estree.js(3902,22): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. +src/language-js/printer-estree.js(3969,14): error TS2339: Property 'comments' does not exist on type 'Expression'. Property 'comments' does not exist on type 'Identifier'. -src/language-js/printer-estree.js(3980,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"OptionalMemberExpression"' have no overlap. -src/language-js/printer-estree.js(3981,13): error TS2339: Property 'property' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. +src/language-js/printer-estree.js(3981,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"OptionalMemberExpression"' have no overlap. +src/language-js/printer-estree.js(3982,13): error TS2339: Property 'property' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. Property 'property' does not exist on type 'SimpleLiteral'. -src/language-js/printer-estree.js(3981,52): error TS2339: Property 'property' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. +src/language-js/printer-estree.js(3982,52): error TS2339: Property 'property' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. Property 'property' does not exist on type 'SimpleLiteral'. -src/language-js/printer-estree.js(3986,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"OptionalMemberExpression"' have no overlap. -src/language-js/printer-estree.js(3988,29): error TS2339: Property 'object' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. +src/language-js/printer-estree.js(3987,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"OptionalMemberExpression"' have no overlap. +src/language-js/printer-estree.js(3989,29): error TS2339: Property 'object' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. Property 'object' does not exist on type 'SimpleLiteral'. -src/language-js/printer-estree.js(3989,22): error TS2339: Property 'comments' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. +src/language-js/printer-estree.js(3990,22): error TS2339: Property 'comments' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. Property 'comments' does not exist on type 'SimpleLiteral'. -src/language-js/printer-estree.js(3995,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"Identifier"' have no overlap. -src/language-js/printer-estree.js(3996,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"ThisExpression"' have no overlap. -src/language-js/printer-estree.js(4200,23): error TS2532: Object is possibly 'undefined'. -src/language-js/printer-estree.js(4201,24): error TS2532: Object is possibly 'undefined'. -src/language-js/printer-estree.js(4557,5): error TS2345: Argument of type '"" | { type: string; parts: any; } | { type: string; contents: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(3996,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"Identifier"' have no overlap. +src/language-js/printer-estree.js(3997,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"ThisExpression"' have no overlap. +src/language-js/printer-estree.js(4201,23): error TS2532: Object is possibly 'undefined'. +src/language-js/printer-estree.js(4202,24): error TS2532: Object is possibly 'undefined'. +src/language-js/printer-estree.js(4558,5): error TS2345: Argument of type '"" | { type: string; parts: any; } | { type: string; contents: any; }' is not assignable to parameter of type 'string'. Type '{ type: string; parts: any; }' is not assignable to type 'string'. -src/language-js/printer-estree.js(4561,16): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. -src/language-js/printer-estree.js(4609,11): error TS2322: Type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }' is not assignable to type 'string'. -src/language-js/printer-estree.js(4624,11): error TS2322: Type '{ type: string; parts: any; }' is not assignable to type 'string'. -src/language-js/printer-estree.js(4636,9): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. -src/language-js/printer-estree.js(4923,9): error TS2554: Expected 0-2 arguments, but got 3. -src/language-js/printer-estree.js(6130,7): error TS2769: No overload matches this call. +src/language-js/printer-estree.js(4562,16): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(4610,11): error TS2322: Type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }' is not assignable to type 'string'. +src/language-js/printer-estree.js(4625,11): error TS2322: Type '{ type: string; parts: any; }' is not assignable to type 'string'. +src/language-js/printer-estree.js(4637,9): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(4931,9): error TS2554: Expected 0-2 arguments, but got 3. +src/language-js/printer-estree.js(6138,7): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<(childPath: any) => any>[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type 'ConcatArray<(childPath: any) => any>'. - Types of property 'slice' are incompatible. - Type '(start?: number | undefined, end?: number | undefined) => (string | number)[]' is not assignable to type '(start?: number | undefined, end?: number | undefined) => ((childPath: any) => any)[]'. - Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. - Type 'string | number' is not assignable to type '(childPath: any) => any'. - Type 'string' is not assignable to type '(childPath: any) => any'. + The types returned by 'slice(...)' are incompatible between these types. + Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. + Type 'string | number' is not assignable to type '(childPath: any) => any'. + Type 'string' is not assignable to type '(childPath: any) => any'. Overload 2 of 2, '(...items: (((childPath: any) => any) | ConcatArray<(childPath: any) => any>)[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type '((childPath: any) => any) | ConcatArray<(childPath: any) => any>'. Type '(string | number)[]' is not assignable to type 'ConcatArray<(childPath: any) => any>'.