From 015a472a6e12639ab1f50074d2ccc5db14565ef2 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 11 Feb 2020 14:11:59 -0800 Subject: [PATCH 1/3] Fix getTypeAtLocation for `as const` to not issue a diagnostic --- src/compiler/checker.ts | 5 +++++ src/testRunner/unittests/programApi.ts | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f7d72d3950e49..ecd185452ce0b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11336,6 +11336,11 @@ namespace ts { function getTypeFromTypeReference(node: TypeReferenceType): Type { const links = getNodeLinks(node); if (!links.resolvedType) { + // handle LS queries on the `const` in `x as const` by resolving to the type of `x` + if (isTypeReferenceNode(node) && isIdentifier(node.typeName) && idText(node.typeName) === "const" && isAssertionExpression(node.parent)) { + links.resolvedSymbol = unknownSymbol; + return links.resolvedType = checkExpressionCached(node.parent.expression); + } let symbol: Symbol | undefined; let type: Type | undefined; const meaning = SymbolFlags.Type; diff --git a/src/testRunner/unittests/programApi.ts b/src/testRunner/unittests/programApi.ts index 5f5251afaf253..9c65a54ab758d 100644 --- a/src/testRunner/unittests/programApi.ts +++ b/src/testRunner/unittests/programApi.ts @@ -178,4 +178,19 @@ namespace ts { assert.isNotNaN(program.getIdentifierCount()); }); }); + + + describe("unittests:: programApi:: Program.getDiagnosticsProducingTypeChecker / Program.getSemanticDiagnostics", () => { + it("does not produce errors on `as const` it would not normally produce on the command line", () => { + const main = new documents.TextDocument("/main.ts", '0 as const'); + + const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [main], cwd: "/" }); + const program = createProgram(["/main.ts"], {}, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed })); + const typeChecker = program.getDiagnosticsProducingTypeChecker(); + const sourceFile = program.getSourceFile("main.ts")!; + typeChecker.getTypeAtLocation(((sourceFile.statements[0] as ExpressionStatement).expression as AsExpression).type); + const diag = program.getSemanticDiagnostics(); + assert.isEmpty(diag); + }); + }); } From 6feb34997c3a26ac4576b813beefd719758c847d Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 11 Feb 2020 14:18:04 -0800 Subject: [PATCH 2/3] use existing helpers for checks --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ecd185452ce0b..e1a25d6b87140 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11337,7 +11337,7 @@ namespace ts { const links = getNodeLinks(node); if (!links.resolvedType) { // handle LS queries on the `const` in `x as const` by resolving to the type of `x` - if (isTypeReferenceNode(node) && isIdentifier(node.typeName) && idText(node.typeName) === "const" && isAssertionExpression(node.parent)) { + if (isConstTypeReference(node) && isAssertionExpression(node.parent)) { links.resolvedSymbol = unknownSymbol; return links.resolvedType = checkExpressionCached(node.parent.expression); } From 8bcd4f4c5ca528fd6ecef9419c92b00ef47d2bec Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 11 Feb 2020 14:32:21 -0800 Subject: [PATCH 3/3] Fix lint --- src/testRunner/unittests/programApi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testRunner/unittests/programApi.ts b/src/testRunner/unittests/programApi.ts index 9c65a54ab758d..51405aece41a3 100644 --- a/src/testRunner/unittests/programApi.ts +++ b/src/testRunner/unittests/programApi.ts @@ -182,7 +182,7 @@ namespace ts { describe("unittests:: programApi:: Program.getDiagnosticsProducingTypeChecker / Program.getSemanticDiagnostics", () => { it("does not produce errors on `as const` it would not normally produce on the command line", () => { - const main = new documents.TextDocument("/main.ts", '0 as const'); + const main = new documents.TextDocument("/main.ts", "0 as const"); const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { documents: [main], cwd: "/" }); const program = createProgram(["/main.ts"], {}, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed }));