From 062f97a6fa4532487a8d78e2eb798bdd2aa06103 Mon Sep 17 00:00:00 2001 From: Wenlu Wang <805037171@163.com> Date: Wed, 10 Jan 2018 01:24:00 +0800 Subject: [PATCH] allow const enum in type query (#21083) --- src/compiler/checker.ts | 5 ++- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/constEnum3.js | 20 +++++++++ tests/baselines/reference/constEnum3.symbols | 38 ++++++++++++++++ tests/baselines/reference/constEnum3.types | 44 +++++++++++++++++++ .../reference/constEnumErrors.errors.txt | 12 ++--- .../constEnumPropertyAccess2.errors.txt | 4 +- .../conformance/constEnums/constEnum3.ts | 10 +++++ 8 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/constEnum3.js create mode 100644 tests/baselines/reference/constEnum3.symbols create mode 100644 tests/baselines/reference/constEnum3.types create mode 100644 tests/cases/conformance/constEnums/constEnum3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ef107c2bc68..9455b659c08 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19474,10 +19474,11 @@ namespace ts { const ok = (node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).expression === node) || (node.parent.kind === SyntaxKind.ElementAccessExpression && (node.parent).expression === node) || - ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node)); + ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node) || + (node.parent.kind === SyntaxKind.TypeQuery && (node.parent).exprName === node)); if (!ok) { - error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment); + error(node, Diagnostics.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); } } return type; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4fa32251549..3fc415b37a0 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1620,7 +1620,7 @@ "category": "Error", "code": 2474 }, - "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.": { + "'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.": { "category": "Error", "code": 2475 }, diff --git a/tests/baselines/reference/constEnum3.js b/tests/baselines/reference/constEnum3.js new file mode 100644 index 00000000000..c219975d10f --- /dev/null +++ b/tests/baselines/reference/constEnum3.js @@ -0,0 +1,20 @@ +//// [constEnum3.ts] +const enum TestType { foo, bar } +type TestTypeStr = keyof typeof TestType; + +function f1(f: TestType) { } +function f2(f: TestTypeStr) { } + +f1(TestType.foo) +f1(TestType.bar) +f2('foo') +f2('bar') + + +//// [constEnum3.js] +function f1(f) { } +function f2(f) { } +f1(0 /* foo */); +f1(1 /* bar */); +f2('foo'); +f2('bar'); diff --git a/tests/baselines/reference/constEnum3.symbols b/tests/baselines/reference/constEnum3.symbols new file mode 100644 index 00000000000..159d866c9a6 --- /dev/null +++ b/tests/baselines/reference/constEnum3.symbols @@ -0,0 +1,38 @@ +=== tests/cases/conformance/constEnums/constEnum3.ts === +const enum TestType { foo, bar } +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) +>bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) + +type TestTypeStr = keyof typeof TestType; +>TestTypeStr : Symbol(TestTypeStr, Decl(constEnum3.ts, 0, 32)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) + +function f1(f: TestType) { } +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>f : Symbol(f, Decl(constEnum3.ts, 3, 12)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) + +function f2(f: TestTypeStr) { } +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) +>f : Symbol(f, Decl(constEnum3.ts, 4, 12)) +>TestTypeStr : Symbol(TestTypeStr, Decl(constEnum3.ts, 0, 32)) + +f1(TestType.foo) +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>TestType.foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) + +f1(TestType.bar) +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>TestType.bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) + +f2('foo') +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) + +f2('bar') +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) + diff --git a/tests/baselines/reference/constEnum3.types b/tests/baselines/reference/constEnum3.types new file mode 100644 index 00000000000..fd14b87e0da --- /dev/null +++ b/tests/baselines/reference/constEnum3.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/constEnums/constEnum3.ts === +const enum TestType { foo, bar } +>TestType : TestType +>foo : TestType.foo +>bar : TestType.bar + +type TestTypeStr = keyof typeof TestType; +>TestTypeStr : "foo" | "bar" +>TestType : typeof TestType + +function f1(f: TestType) { } +>f1 : (f: TestType) => void +>f : TestType +>TestType : TestType + +function f2(f: TestTypeStr) { } +>f2 : (f: "foo" | "bar") => void +>f : "foo" | "bar" +>TestTypeStr : "foo" | "bar" + +f1(TestType.foo) +>f1(TestType.foo) : void +>f1 : (f: TestType) => void +>TestType.foo : TestType.foo +>TestType : typeof TestType +>foo : TestType.foo + +f1(TestType.bar) +>f1(TestType.bar) : void +>f1 : (f: TestType) => void +>TestType.bar : TestType.bar +>TestType : typeof TestType +>bar : TestType.bar + +f2('foo') +>f2('foo') : void +>f2 : (f: "foo" | "bar") => void +>'foo' : "foo" + +f2('bar') +>f2('bar') : void +>f2 : (f: "foo" | "bar") => void +>'bar' : "bar" + diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index 586652d41eb..c2642c9b1ac 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -5,9 +5,9 @@ tests/cases/compiler/constEnumErrors.ts(14,9): error TS2474: In 'const' enum dec tests/cases/compiler/constEnumErrors.ts(15,10): error TS2474: In 'const' enum declarations member initializer must be constant expression. 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. -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. -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. +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(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'. @@ -55,17 +55,17 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member var x = E2; ~~ -!!! 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. +!!! 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. var y = [E2]; ~~ -!!! 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. +!!! 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. function foo(t: any): void { } foo(E2); ~~ -!!! 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. +!!! 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. const enum NaNOrInfinity { A = 9007199254740992, diff --git a/tests/baselines/reference/constEnumPropertyAccess2.errors.txt b/tests/baselines/reference/constEnumPropertyAccess2.errors.txt index aa08c11c7a2..40731d3ad54 100644 --- a/tests/baselines/reference/constEnumPropertyAccess2.errors.txt +++ b/tests/baselines/reference/constEnumPropertyAccess2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(13,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. +tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(13,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/conformance/constEnums/constEnumPropertyAccess2.ts(14,12): error TS2476: A const enum member can only be accessed using a string literal. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(16,1): error TS2322: Type '"string"' is not assignable to type 'G'. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(18,3): error TS2540: Cannot assign to 'B' because it is a constant or a read-only property. @@ -19,7 +19,7 @@ tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(18,3): error TS25 // Error from referring constant enum in any other context than a property access var z = G; ~ -!!! 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. +!!! 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. var z1 = G[G.A]; ~~~ !!! error TS2476: A const enum member can only be accessed using a string literal. diff --git a/tests/cases/conformance/constEnums/constEnum3.ts b/tests/cases/conformance/constEnums/constEnum3.ts new file mode 100644 index 00000000000..ffc6bb1c5f5 --- /dev/null +++ b/tests/cases/conformance/constEnums/constEnum3.ts @@ -0,0 +1,10 @@ +const enum TestType { foo, bar } +type TestTypeStr = keyof typeof TestType; + +function f1(f: TestType) { } +function f2(f: TestTypeStr) { } + +f1(TestType.foo) +f1(TestType.bar) +f2('foo') +f2('bar')