From 162ad55052493fb2ebb5e9cfd441d0543512c1bb Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 7 May 2021 09:44:01 -0700 Subject: [PATCH 1/6] Add compiler option --- src/compiler/commandLineParser.ts | 7 ++++--- src/compiler/types.ts | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 253e38a5295b5..d79e7e180ef2c 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -536,9 +536,10 @@ namespace ts { { name: "importsNotUsedAsValues", type: new Map(getEntries({ - remove: ImportsNotUsedAsValues.Remove, - preserve: ImportsNotUsedAsValues.Preserve, - error: ImportsNotUsedAsValues.Error + "remove": ImportsNotUsedAsValues.Remove, + "preserve": ImportsNotUsedAsValues.Preserve, + "error": ImportsNotUsedAsValues.Error, + "preserve-exact": ImportsNotUsedAsValues.PreserveExact, })), affectsEmit: true, affectsSemanticDiagnostics: true, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f7183d7dd6c27..0fc47a278363b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6070,7 +6070,8 @@ namespace ts { export const enum ImportsNotUsedAsValues { Remove, Preserve, - Error + Error, + PreserveExact, } export const enum NewLineKind { From da436399c5036d3d1c1226895772508711b29d7f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 7 May 2021 09:44:27 -0700 Subject: [PATCH 2/6] Require es2015+ --- src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/program.ts | 10 +++++++--- ...es_preserve-exact_module(module=amd).errors.txt | 7 +++++++ ...edAsValues_preserve-exact_module(module=amd).js | 9 +++++++++ ...eserve-exact_module(module=commonjs).errors.txt | 7 +++++++ ...alues_preserve-exact_module(module=commonjs).js | 7 +++++++ ...sValues_preserve-exact_module(module=es2015).js | 6 ++++++ ...preserve-exact_module(module=system).errors.txt | 7 +++++++ ...sValues_preserve-exact_module(module=system).js | 14 ++++++++++++++ ...importsNotUsedAsValues_preserve-exact_module.ts | 4 ++++ 10 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).errors.txt create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).js create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).errors.txt create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).js create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=es2015).js create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).errors.txt create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).js create mode 100644 tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f4fbe932e93f9..cf7c1878d81ab 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3942,6 +3942,10 @@ "category": "Error", "code": 5094 }, + "Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later.": { + "category": "Error", + "code": 5095 + }, "Generates a sourcemap for each corresponding '.d.ts' file.": { "category": "Message", diff --git a/src/compiler/program.ts b/src/compiler/program.ts index a50b60a3171b2..c7af1680fe108 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3295,6 +3295,10 @@ namespace ts { } } + if (options.importsNotUsedAsValues === ImportsNotUsedAsValues.PreserveExact && getEmitModuleKind(options) < ModuleKind.ES2015) { + createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_importsNotUsedAsValues_may_only_be_set_to_preserve_exact_when_module_is_set_to_es2015_or_later); + } + // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files if (!options.noEmit && !options.suppressOutputPathCheck) { const emitHost = getEmitHost(); @@ -3565,7 +3569,7 @@ namespace ts { createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3); } - function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0: string) { + function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0?: string) { createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0); } @@ -3580,7 +3584,7 @@ namespace ts { } } - function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number) { + function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) { const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax || !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2); @@ -3606,7 +3610,7 @@ namespace ts { return _compilerOptionsObjectLiteralSyntax || undefined; } - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number): boolean { + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): boolean { const props = getPropertyAssignment(objectLiteral, key1, key2); for (const prop of props) { programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2)); diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).errors.txt new file mode 100644 index 0000000000000..78cda02c61432 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).errors.txt @@ -0,0 +1,7 @@ +error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. + + +!!! error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +==== tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts (0 errors) ==== + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).js b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).js new file mode 100644 index 0000000000000..e09b7569742cb --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).js @@ -0,0 +1,9 @@ +//// [importsNotUsedAsValues_preserve-exact_module.ts] +export {}; + + +//// [importsNotUsedAsValues_preserve-exact_module.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.__esModule = true; +}); diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).errors.txt new file mode 100644 index 0000000000000..78cda02c61432 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).errors.txt @@ -0,0 +1,7 @@ +error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. + + +!!! error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +==== tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts (0 errors) ==== + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).js b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).js new file mode 100644 index 0000000000000..0ab551b173b93 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).js @@ -0,0 +1,7 @@ +//// [importsNotUsedAsValues_preserve-exact_module.ts] +export {}; + + +//// [importsNotUsedAsValues_preserve-exact_module.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=es2015).js b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=es2015).js new file mode 100644 index 0000000000000..3abff4aa677b1 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=es2015).js @@ -0,0 +1,6 @@ +//// [importsNotUsedAsValues_preserve-exact_module.ts] +export {}; + + +//// [importsNotUsedAsValues_preserve-exact_module.js] +export {}; diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).errors.txt new file mode 100644 index 0000000000000..78cda02c61432 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).errors.txt @@ -0,0 +1,7 @@ +error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. + + +!!! error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +==== tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts (0 errors) ==== + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).js b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).js new file mode 100644 index 0000000000000..87284733faf13 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).js @@ -0,0 +1,14 @@ +//// [importsNotUsedAsValues_preserve-exact_module.ts] +export {}; + + +//// [importsNotUsedAsValues_preserve-exact_module.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + } + }; +}); diff --git a/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts b/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts new file mode 100644 index 0000000000000..9dde082758e95 --- /dev/null +++ b/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts @@ -0,0 +1,4 @@ +// @importsNotUsedAsValues: preserve-exact +// @module: amd,system,commonjs,es2015 +// @noTypesAndSymbols: true +export {}; From a755070e45a5aef610d03f452e7c8e34395fc131 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 7 May 2021 10:13:43 -0700 Subject: [PATCH 3/6] Do not elide any imports or exports in preserve-exact --- src/compiler/transformers/ts.ts | 21 +++++---- ...sNotUsedAsValues_preserve-exact.errors.txt | 35 ++++++++++++++ .../importsNotUsedAsValues_preserve-exact.js | 43 +++++++++++++++++ ...ortsNotUsedAsValues_preserve-exact.symbols | 42 +++++++++++++++++ ...mportsNotUsedAsValues_preserve-exact.types | 47 +++++++++++++++++++ .../importsNotUsedAsValues_preserve-exact.ts | 26 ++++++++++ 6 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact.errors.txt create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact.js create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact.symbols create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact.types create mode 100644 tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact.ts diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0d24f332c15bd..4cdb1df730944 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -46,6 +46,7 @@ namespace ts { const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks"); const languageVersion = getEmitScriptTarget(compilerOptions); const moduleKind = getEmitModuleKind(compilerOptions); + const { importsNotUsedAsValues } = compilerOptions; // Save the previous transformation hooks. const previousOnEmitNode = context.onEmitNode; @@ -2802,7 +2803,7 @@ namespace ts { } /** - * Visits an import declaration, eliding it if it is not referenced and `importsNotUsedAsValues` is not 'preserve'. + * Visits an import declaration, eliding it if it is not referenced and `importsNotUsedAsValues` is not 'preserve' or 'preserve-exact'. * * @param node The import declaration node. */ @@ -2820,8 +2821,9 @@ namespace ts { // Elide the declaration if the import clause was elided. const importClause = visitNode(node.importClause, visitImportClause, isImportClause); return importClause || - compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve || - compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error + importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve || + importsNotUsedAsValues === ImportsNotUsedAsValues.PreserveExact || + importsNotUsedAsValues === ImportsNotUsedAsValues.Error ? factory.updateImportDeclaration( node, /*decorators*/ undefined, @@ -2832,13 +2834,14 @@ namespace ts { } /** - * Visits an import clause, eliding it if it is not referenced. + * Visits an import clause, eliding it if it is not referenced and `importsNotUsedAsValues` is not 'preserve-exact'. * * @param node The import clause node. */ function visitImportClause(node: ImportClause): VisitResult { - if (node.isTypeOnly) { - return undefined; + Debug.assert(!node.isTypeOnly); + if (importsNotUsedAsValues === ImportsNotUsedAsValues.PreserveExact) { + return node; } // Elide the import clause if we elide both its name and its named bindings. const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined; @@ -2888,7 +2891,7 @@ namespace ts { /** * Visits an export declaration, eliding it if it does not contain a clause that resolves - * to a value. + * to a value and if `importsNotUsedAsValues` is not 'preserve-exact'. * * @param node The export declaration node. */ @@ -2897,7 +2900,7 @@ namespace ts { return undefined; } - if (!node.exportClause || isNamespaceExport(node.exportClause)) { + if (!node.exportClause || isNamespaceExport(node.exportClause) || importsNotUsedAsValues === ImportsNotUsedAsValues.PreserveExact) { // never elide `export from ` declarations - // they should be kept for sideffects/untyped exports, even when the // type checker doesn't know about any exports @@ -2980,7 +2983,7 @@ namespace ts { if (isExternalModuleImportEqualsDeclaration(node)) { const isReferenced = resolver.isReferencedAliasDeclaration(node); // If the alias is unreferenced but we want to keep the import, replace with 'import "mod"'. - if (!isReferenced && compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve) { + if (!isReferenced && importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve) { return setOriginalNode( setTextRange( factory.createImportDeclaration( diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.errors.txt new file mode 100644 index 0000000000000..c90a89d4bda8c --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.errors.txt @@ -0,0 +1,35 @@ +tests/cases/conformance/externalModules/typeOnly/d.ts(1,1): error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead. +tests/cases/conformance/externalModules/typeOnly/e.ts(1,1): error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead. +tests/cases/conformance/externalModules/typeOnly/e.ts(2,1): error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead. + + +==== tests/cases/conformance/externalModules/typeOnly/a.ts (0 errors) ==== + export default {}; + export const b = 0; + export const c = 1; + +==== tests/cases/conformance/externalModules/typeOnly/b.ts (0 errors) ==== + import a, { b, c } from "./a"; + +==== tests/cases/conformance/externalModules/typeOnly/c.ts (0 errors) ==== + import * as a from "./a"; + +==== tests/cases/conformance/externalModules/typeOnly/d.ts (1 errors) ==== + export = {}; + ~~~~~~~~~~~~ +!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead. + +==== tests/cases/conformance/externalModules/typeOnly/e.ts (2 errors) ==== + import D = require("./d"); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead. + import DD = require("./d"); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead. + DD; + +==== tests/cases/conformance/externalModules/typeOnly/f.ts (0 errors) ==== + import type a from "./a"; + import { b, c } from "./a"; + b; + \ No newline at end of file diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.js b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.js new file mode 100644 index 0000000000000..20050b1c3d625 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.js @@ -0,0 +1,43 @@ +//// [tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact.ts] //// + +//// [a.ts] +export default {}; +export const b = 0; +export const c = 1; + +//// [b.ts] +import a, { b, c } from "./a"; + +//// [c.ts] +import * as a from "./a"; + +//// [d.ts] +export = {}; + +//// [e.ts] +import D = require("./d"); +import DD = require("./d"); +DD; + +//// [f.ts] +import type a from "./a"; +import { b, c } from "./a"; +b; + + +//// [a.js] +export default {}; +export var b = 0; +export var c = 1; +//// [b.js] +import a, { b, c } from "./a"; +//// [c.js] +import * as a from "./a"; +//// [d.js] +export {}; +//// [e.js] +DD; +export {}; +//// [f.js] +import { b, c } from "./a"; +b; diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.symbols b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.symbols new file mode 100644 index 0000000000000..c1fe6176415a8 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.symbols @@ -0,0 +1,42 @@ +=== tests/cases/conformance/externalModules/typeOnly/a.ts === +export default {}; +export const b = 0; +>b : Symbol(b, Decl(a.ts, 1, 12)) + +export const c = 1; +>c : Symbol(c, Decl(a.ts, 2, 12)) + +=== tests/cases/conformance/externalModules/typeOnly/b.ts === +import a, { b, c } from "./a"; +>a : Symbol(a, Decl(b.ts, 0, 6)) +>b : Symbol(b, Decl(b.ts, 0, 11)) +>c : Symbol(c, Decl(b.ts, 0, 14)) + +=== tests/cases/conformance/externalModules/typeOnly/c.ts === +import * as a from "./a"; +>a : Symbol(a, Decl(c.ts, 0, 6)) + +=== tests/cases/conformance/externalModules/typeOnly/d.ts === +export = {}; +No type information for this code. +No type information for this code.=== tests/cases/conformance/externalModules/typeOnly/e.ts === +import D = require("./d"); +>D : Symbol(D, Decl(e.ts, 0, 0)) + +import DD = require("./d"); +>DD : Symbol(DD, Decl(e.ts, 0, 26)) + +DD; +>DD : Symbol(DD, Decl(e.ts, 0, 26)) + +=== tests/cases/conformance/externalModules/typeOnly/f.ts === +import type a from "./a"; +>a : Symbol(a, Decl(f.ts, 0, 6)) + +import { b, c } from "./a"; +>b : Symbol(b, Decl(f.ts, 1, 8)) +>c : Symbol(c, Decl(f.ts, 1, 11)) + +b; +>b : Symbol(b, Decl(f.ts, 1, 8)) + diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.types b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.types new file mode 100644 index 0000000000000..ed58db4b453d4 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact.types @@ -0,0 +1,47 @@ +=== tests/cases/conformance/externalModules/typeOnly/a.ts === +export default {}; +>{} : {} + +export const b = 0; +>b : 0 +>0 : 0 + +export const c = 1; +>c : 1 +>1 : 1 + +=== tests/cases/conformance/externalModules/typeOnly/b.ts === +import a, { b, c } from "./a"; +>a : {} +>b : 0 +>c : 1 + +=== tests/cases/conformance/externalModules/typeOnly/c.ts === +import * as a from "./a"; +>a : typeof a + +=== tests/cases/conformance/externalModules/typeOnly/d.ts === +export = {}; +>{} : {} + +=== tests/cases/conformance/externalModules/typeOnly/e.ts === +import D = require("./d"); +>D : {} + +import DD = require("./d"); +>DD : {} + +DD; +>DD : {} + +=== tests/cases/conformance/externalModules/typeOnly/f.ts === +import type a from "./a"; +>a : any + +import { b, c } from "./a"; +>b : 0 +>c : 1 + +b; +>b : 0 + diff --git a/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact.ts b/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact.ts new file mode 100644 index 0000000000000..ceab3ba2dfdfc --- /dev/null +++ b/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact.ts @@ -0,0 +1,26 @@ +// @importsNotUsedAsValues: preserve-exact +// @module: esnext + +// @Filename: a.ts +export default {}; +export const b = 0; +export const c = 1; + +// @Filename: b.ts +import a, { b, c } from "./a"; + +// @Filename: c.ts +import * as a from "./a"; + +// @Filename: d.ts +export = {}; + +// @Filename: e.ts +import D = require("./d"); +import DD = require("./d"); +DD; + +// @Filename: f.ts +import type a from "./a"; +import { b, c } from "./a"; +b; From 8dd24559a63f60fca2a5a687f1384fd8450febdd Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 17 May 2021 16:14:19 -0700 Subject: [PATCH 4/6] Add errors for writing imports/exports that reference elided names --- src/compiler/checker.ts | 76 ++++++++++++--- src/compiler/diagnosticMessages.json | 20 ++++ ...dAsValues_preserve-exact_errors.errors.txt | 81 ++++++++++++++++ ...tsNotUsedAsValues_preserve-exact_errors.js | 77 +++++++++++++++ ...UsedAsValues_preserve-exact_errors.symbols | 95 +++++++++++++++++++ ...otUsedAsValues_preserve-exact_errors.types | 95 +++++++++++++++++++ .../isolatedModulesReExportType.errors.txt | 17 +++- .../reference/isolatedModulesReExportType.js | 14 +++ .../isolatedModulesReExportType.symbols | 20 ++++ .../isolatedModulesReExportType.types | 22 ++++- .../compiler/isolatedModulesReExportType.ts | 11 +++ ...tsNotUsedAsValues_preserve-exact_errors.ts | 46 +++++++++ 12 files changed, 560 insertions(+), 14 deletions(-) create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.errors.txt create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.js create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.symbols create mode 100644 tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.types create mode 100644 tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_errors.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c9cb3fd285482..2c6a6d1076fd4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2166,17 +2166,25 @@ namespace ts { const message = isExport ? Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type : Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type; - const relatedMessage = isExport - ? Diagnostics._0_was_exported_here - : Diagnostics._0_was_imported_here; const unescapedName = unescapeLeadingUnderscores(name); - addRelatedInfo( + addTypeOnlyDeclarationRelatedInfo( error(useSite, message, unescapedName), - createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, unescapedName)); + typeOnlyDeclaration, + unescapedName); } } } + function addTypeOnlyDeclarationRelatedInfo(diagnostic: Diagnostic, typeOnlyDeclaration: TypeOnlyCompatibleAliasDeclaration | undefined, unescapedName: string) { + if (!typeOnlyDeclaration) return diagnostic; + return addRelatedInfo( + diagnostic, + createDiagnosticForNode( + typeOnlyDeclaration, + typeOnlyDeclarationIsExport(typeOnlyDeclaration) ? Diagnostics._0_was_exported_here : Diagnostics._0_was_imported_here, + unescapedName)); + } + function getIsDeferredContext(location: Node, lastLocation: Node | undefined): boolean { if (location.kind !== SyntaxKind.ArrowFunction && location.kind !== SyntaxKind.FunctionExpression) { // initializers in instance property declaration of class like entities are executed in constructor and thus deferred @@ -38072,13 +38080,57 @@ namespace ts { error(node, message, symbolToString(symbol)); } - // Don't allow to re-export something with no value side when `--isolatedModules` is set. - if (compilerOptions.isolatedModules - && node.kind === SyntaxKind.ExportSpecifier - && !node.parent.parent.isTypeOnly - && !(target.flags & SymbolFlags.Value) - && !(node.flags & NodeFlags.Ambient)) { - error(node, Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type); + const isDeclaredTypeOnly = isTypeOnlyImportOrExportDeclaration(node); + if ((compilerOptions.isolatedModules || compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.PreserveExact) + && !isDeclaredTypeOnly + && !(node.flags & NodeFlags.Ambient) + && (!(target.flags & SymbolFlags.Value) || getTypeOnlyAliasDeclaration(symbol))) { + const isType = !(target.flags & SymbolFlags.Value); + const typeOnlyAlias = getTypeOnlyAliasDeclaration(symbol); + + switch (node.kind) { + case SyntaxKind.ImportClause: + case SyntaxKind.ImportSpecifier: + case SyntaxKind.ImportEqualsDeclaration: { + if (compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.PreserveExact) { + const message = isType + ? Diagnostics._0_is_a_type_and_must_be_imported_with_a_type_only_import_when_importsNotUsedAsValues_is_set_to_preserve_exact + : Diagnostics._0_resolves_to_a_type_only_reference_and_must_be_imported_with_a_type_only_import_when_importsNotUsedAsValues_is_set_to_preserve_exact; + const name = idText(node.kind === SyntaxKind.ImportSpecifier ? node.propertyName || node.name : node.name!); + addTypeOnlyDeclarationRelatedInfo( + error(node, message, name), + isType ? undefined : typeOnlyAlias, + name + ); + } + break; + } + case SyntaxKind.ExportSpecifier: { + // Don't allow re-exporting an export that will be elided when `--isolatedModules` is set + // or when `--importsNotUsedAsValues` is `preserve-exact`. + if (compilerOptions.isolatedModules && + compilerOptions.importsNotUsedAsValues !== ImportsNotUsedAsValues.PreserveExact && + typeOnlyAlias && getSourceFileOfNode(typeOnlyAlias) === getSourceFileOfNode(node)) { + // In `isolatedModules` alone, `import type { A } from './a'; export { A }` is allowed + // because single-file analysis can determine that the export should be dropped. + // `--importsNotUsedAsValues=preserv-exact` is stricter; it refuses to touch non-type-only + // imports and exports, so `export { A }` is not allowed if 'A' is not emitted. + return; + } + const message = + compilerOptions.isolatedModules && isType ? Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type : + compilerOptions.isolatedModules && !isType ? Diagnostics._0_resolves_to_a_type_only_reference_and_must_be_re_exported_with_a_type_only_re_export_when_isolatedModules_is_enabled : + isType ? Diagnostics._0_is_a_type_and_must_be_re_exported_with_a_type_only_re_export_when_importsNotUsedAsValues_is_set_to_preserve_exact : + Diagnostics._0_resolves_to_a_type_only_reference_and_must_be_re_exported_with_a_type_only_re_export_when_importsNotUsedAsValues_is_set_to_preserve_exact; + const name = idText(node.propertyName || node.name); + addTypeOnlyDeclarationRelatedInfo( + error(node, message, name), + isType ? undefined : typeOnlyAlias, + name + ); + return; + } + } } if (isImportSpecifier(node) && target.declarations?.every(d => !!(getCombinedNodeFlags(d) & NodeFlags.Deprecated))) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cf7c1878d81ab..e8232cd2a7d47 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1364,6 +1364,26 @@ "category": "Error", "code": 1433 }, + "'{0}' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'.": { + "category": "Error", + "code": 1434 + }, + "'{0}' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'.": { + "category": "Error", + "code": 1435 + }, + "'{0}' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'.": { + "category": "Error", + "code": 1436 + }, + "'{0}' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'.": { + "category": "Error", + "code": 1437 + }, + "'{0}' resolves to a type-only reference and must be re-exported with a type-only re-export when 'isolatedModules' is enabled.": { + "category": "Error", + "code": 1438 + }, "The types of '{0}' are incompatible between these types.": { "category": "Error", diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.errors.txt new file mode 100644 index 0000000000000..52342ce13a8e9 --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.errors.txt @@ -0,0 +1,81 @@ +tests/cases/conformance/externalModules/typeOnly/c.ts(1,8): error TS1434: 'DefaultA' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/c.ts(2,10): error TS1434: 'A' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/c.ts(3,8): error TS1436: 'DefaultB' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/c.ts(4,10): error TS1436: 'B' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/d.ts(1,10): error TS1435: 'A' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/d.ts(2,10): error TS1437: 'B' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/e.ts(1,10): error TS1434: 'AA' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/e.ts(1,14): error TS1436: 'BB' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/f.ts(3,10): error TS1435: 'A' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/f.ts(3,13): error TS1437: 'B' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. + + +==== tests/cases/conformance/externalModules/typeOnly/a.ts (0 errors) ==== + export type A = {}; + export type { A as default }; + +==== tests/cases/conformance/externalModules/typeOnly/b.ts (0 errors) ==== + class B {}; + export type { B, B as default }; + +==== tests/cases/conformance/externalModules/typeOnly/c.ts (4 errors) ==== + import DefaultA from "./a"; + ~~~~~~~~ +!!! error TS1434: 'DefaultA' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. + import { A } from "./a"; + ~ +!!! error TS1434: 'A' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. + import DefaultB from "./b"; + ~~~~~~~~ +!!! error TS1436: 'DefaultB' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:18: 'DefaultB' was exported here. + import { B } from "./b"; + ~ +!!! error TS1436: 'B' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:15: 'B' was exported here. + +==== tests/cases/conformance/externalModules/typeOnly/c.fixed.ts (0 errors) ==== + import type DefaultA from "./a"; + import type { A } from "./a"; + import type DefaultB from "./b"; + import type { B } from "./b"; + +==== tests/cases/conformance/externalModules/typeOnly/d.ts (2 errors) ==== + export { A as AA } from "./a"; + ~~~~~~~ +!!! error TS1435: 'A' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. + export { B as BB } from "./b"; + ~~~~~~~ +!!! error TS1437: 'B' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:15: 'B' was exported here. + +==== tests/cases/conformance/externalModules/typeOnly/d.fixed.ts (0 errors) ==== + export type { A as AA } from "./a"; + export type { B as BB } from "./b"; + +==== tests/cases/conformance/externalModules/typeOnly/e.ts (2 errors) ==== + import { AA, BB } from "./d"; + ~~ +!!! error TS1434: 'AA' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. + ~~ +!!! error TS1436: 'BB' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:15: 'BB' was exported here. + +==== tests/cases/conformance/externalModules/typeOnly/e.fixed.ts (0 errors) ==== + import type { AA, BB } from "./d"; + +==== tests/cases/conformance/externalModules/typeOnly/f.ts (2 errors) ==== + import type { A } from "./a"; + import type { B } from "./b"; + export { A, B as BB }; + ~ +!!! error TS1435: 'A' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. + ~~~~~~~ +!!! error TS1437: 'B' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/f.ts:2:15: 'B' was imported here. + +==== tests/cases/conformance/externalModules/typeOnly/f.fixed.ts (0 errors) ==== + import type { A } from "./a"; + import type { B } from "./b"; + export type { A, B as BB }; + \ No newline at end of file diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.js b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.js new file mode 100644 index 0000000000000..f564805995fdf --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.js @@ -0,0 +1,77 @@ +//// [tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_errors.ts] //// + +//// [a.ts] +export type A = {}; +export type { A as default }; + +//// [b.ts] +class B {}; +export type { B, B as default }; + +//// [c.ts] +import DefaultA from "./a"; +import { A } from "./a"; +import DefaultB from "./b"; +import { B } from "./b"; + +//// [c.fixed.ts] +import type DefaultA from "./a"; +import type { A } from "./a"; +import type DefaultB from "./b"; +import type { B } from "./b"; + +//// [d.ts] +export { A as AA } from "./a"; +export { B as BB } from "./b"; + +//// [d.fixed.ts] +export type { A as AA } from "./a"; +export type { B as BB } from "./b"; + +//// [e.ts] +import { AA, BB } from "./d"; + +//// [e.fixed.ts] +import type { AA, BB } from "./d"; + +//// [f.ts] +import type { A } from "./a"; +import type { B } from "./b"; +export { A, B as BB }; + +//// [f.fixed.ts] +import type { A } from "./a"; +import type { B } from "./b"; +export type { A, B as BB }; + + +//// [a.js] +export {}; +//// [b.js] +var B = /** @class */ (function () { + function B() { + } + return B; +}()); +; +export {}; +//// [c.js] +import DefaultA from "./a"; +import { A } from "./a"; +import DefaultB from "./b"; +import { B } from "./b"; +//// [c.fixed.js] +export {}; +//// [d.js] +export { A as AA } from "./a"; +export { B as BB } from "./b"; +//// [d.fixed.js] +export {}; +//// [e.js] +import { AA, BB } from "./d"; +//// [e.fixed.js] +export {}; +//// [f.js] +export { A, B as BB }; +//// [f.fixed.js] +export {}; diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.symbols b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.symbols new file mode 100644 index 0000000000000..0dd64238caf2a --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.symbols @@ -0,0 +1,95 @@ +=== tests/cases/conformance/externalModules/typeOnly/a.ts === +export type A = {}; +>A : Symbol(A, Decl(a.ts, 0, 0)) + +export type { A as default }; +>A : Symbol(A, Decl(a.ts, 0, 0)) +>default : Symbol(default, Decl(a.ts, 1, 13)) + +=== tests/cases/conformance/externalModules/typeOnly/b.ts === +class B {}; +>B : Symbol(B, Decl(b.ts, 0, 0)) + +export type { B, B as default }; +>B : Symbol(B, Decl(b.ts, 1, 13)) +>B : Symbol(B, Decl(b.ts, 0, 0)) +>default : Symbol(default, Decl(b.ts, 1, 16)) + +=== tests/cases/conformance/externalModules/typeOnly/c.ts === +import DefaultA from "./a"; +>DefaultA : Symbol(DefaultA, Decl(c.ts, 0, 6)) + +import { A } from "./a"; +>A : Symbol(A, Decl(c.ts, 1, 8)) + +import DefaultB from "./b"; +>DefaultB : Symbol(DefaultB, Decl(c.ts, 2, 6)) + +import { B } from "./b"; +>B : Symbol(B, Decl(c.ts, 3, 8)) + +=== tests/cases/conformance/externalModules/typeOnly/c.fixed.ts === +import type DefaultA from "./a"; +>DefaultA : Symbol(DefaultA, Decl(c.fixed.ts, 0, 6)) + +import type { A } from "./a"; +>A : Symbol(A, Decl(c.fixed.ts, 1, 13)) + +import type DefaultB from "./b"; +>DefaultB : Symbol(DefaultB, Decl(c.fixed.ts, 2, 6)) + +import type { B } from "./b"; +>B : Symbol(B, Decl(c.fixed.ts, 3, 13)) + +=== tests/cases/conformance/externalModules/typeOnly/d.ts === +export { A as AA } from "./a"; +>A : Symbol(A, Decl(a.ts, 0, 0)) +>AA : Symbol(AA, Decl(d.ts, 0, 8)) + +export { B as BB } from "./b"; +>B : Symbol(B, Decl(b.ts, 1, 13)) +>BB : Symbol(BB, Decl(d.ts, 1, 8)) + +=== tests/cases/conformance/externalModules/typeOnly/d.fixed.ts === +export type { A as AA } from "./a"; +>A : Symbol(A, Decl(a.ts, 0, 0)) +>AA : Symbol(AA, Decl(d.fixed.ts, 0, 13)) + +export type { B as BB } from "./b"; +>B : Symbol(B, Decl(b.ts, 1, 13)) +>BB : Symbol(BB, Decl(d.fixed.ts, 1, 13)) + +=== tests/cases/conformance/externalModules/typeOnly/e.ts === +import { AA, BB } from "./d"; +>AA : Symbol(AA, Decl(e.ts, 0, 8)) +>BB : Symbol(BB, Decl(e.ts, 0, 12)) + +=== tests/cases/conformance/externalModules/typeOnly/e.fixed.ts === +import type { AA, BB } from "./d"; +>AA : Symbol(AA, Decl(e.fixed.ts, 0, 13)) +>BB : Symbol(BB, Decl(e.fixed.ts, 0, 17)) + +=== tests/cases/conformance/externalModules/typeOnly/f.ts === +import type { A } from "./a"; +>A : Symbol(A, Decl(f.ts, 0, 13)) + +import type { B } from "./b"; +>B : Symbol(B, Decl(f.ts, 1, 13)) + +export { A, B as BB }; +>A : Symbol(A, Decl(f.ts, 2, 8)) +>B : Symbol(B, Decl(f.ts, 1, 13)) +>BB : Symbol(BB, Decl(f.ts, 2, 11)) + +=== tests/cases/conformance/externalModules/typeOnly/f.fixed.ts === +import type { A } from "./a"; +>A : Symbol(A, Decl(f.fixed.ts, 0, 13)) + +import type { B } from "./b"; +>B : Symbol(B, Decl(f.fixed.ts, 1, 13)) + +export type { A, B as BB }; +>A : Symbol(A, Decl(f.fixed.ts, 2, 13)) +>B : Symbol(B, Decl(f.fixed.ts, 1, 13)) +>BB : Symbol(BB, Decl(f.fixed.ts, 2, 16)) + diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.types b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.types new file mode 100644 index 0000000000000..1e8a912ed7ced --- /dev/null +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.types @@ -0,0 +1,95 @@ +=== tests/cases/conformance/externalModules/typeOnly/a.ts === +export type A = {}; +>A : A + +export type { A as default }; +>A : any +>default : A + +=== tests/cases/conformance/externalModules/typeOnly/b.ts === +class B {}; +>B : B + +export type { B, B as default }; +>B : B +>B : typeof B +>default : B + +=== tests/cases/conformance/externalModules/typeOnly/c.ts === +import DefaultA from "./a"; +>DefaultA : any + +import { A } from "./a"; +>A : any + +import DefaultB from "./b"; +>DefaultB : typeof DefaultB + +import { B } from "./b"; +>B : typeof DefaultB + +=== tests/cases/conformance/externalModules/typeOnly/c.fixed.ts === +import type DefaultA from "./a"; +>DefaultA : DefaultA + +import type { A } from "./a"; +>A : DefaultA + +import type DefaultB from "./b"; +>DefaultB : DefaultB + +import type { B } from "./b"; +>B : DefaultB + +=== tests/cases/conformance/externalModules/typeOnly/d.ts === +export { A as AA } from "./a"; +>A : any +>AA : any + +export { B as BB } from "./b"; +>B : typeof import("tests/cases/conformance/externalModules/typeOnly/b").B +>BB : typeof import("tests/cases/conformance/externalModules/typeOnly/b").B + +=== tests/cases/conformance/externalModules/typeOnly/d.fixed.ts === +export type { A as AA } from "./a"; +>A : any +>AA : import("tests/cases/conformance/externalModules/typeOnly/a").A + +export type { B as BB } from "./b"; +>B : typeof import("tests/cases/conformance/externalModules/typeOnly/b").B +>BB : import("tests/cases/conformance/externalModules/typeOnly/b").B + +=== tests/cases/conformance/externalModules/typeOnly/e.ts === +import { AA, BB } from "./d"; +>AA : any +>BB : typeof BB + +=== tests/cases/conformance/externalModules/typeOnly/e.fixed.ts === +import type { AA, BB } from "./d"; +>AA : AA +>BB : BB + +=== tests/cases/conformance/externalModules/typeOnly/f.ts === +import type { A } from "./a"; +>A : A + +import type { B } from "./b"; +>B : B + +export { A, B as BB }; +>A : any +>B : typeof B +>BB : typeof B + +=== tests/cases/conformance/externalModules/typeOnly/f.fixed.ts === +import type { A } from "./a"; +>A : A + +import type { B } from "./b"; +>B : B + +export type { A, B as BB }; +>A : A +>B : typeof B +>BB : B + diff --git a/tests/baselines/reference/isolatedModulesReExportType.errors.txt b/tests/baselines/reference/isolatedModulesReExportType.errors.txt index 299bd0fcf88e6..0b4b3df52077c 100644 --- a/tests/baselines/reference/isolatedModulesReExportType.errors.txt +++ b/tests/baselines/reference/isolatedModulesReExportType.errors.txt @@ -1,8 +1,9 @@ /user.ts(2,10): error TS1205: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'. /user.ts(17,10): error TS1205: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'. +/user.ts(25,10): error TS1438: 'CC' resolves to a type-only reference and must be re-exported with a type-only re-export when 'isolatedModules' is enabled. -==== /user.ts (2 errors) ==== +==== /user.ts (3 errors) ==== // Error, can't re-export something that's only a type. export { T } from "./exportT"; ~ @@ -25,6 +26,17 @@ ~~~~~~~ !!! error TS1205: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'. + // Ok, type-only import indicates that the export can be elided. + import type { T as TT } from "./exportT"; + export { TT }; + + // Error, type-only declaration is in a different file. + import { C as CC } from "./reExportValueAsTypeOnly"; + export { CC }; + ~~ +!!! error TS1438: 'CC' resolves to a type-only reference and must be re-exported with a type-only re-export when 'isolatedModules' is enabled. +!!! related TS1377 /reExportValueAsTypeOnly.ts:1:15: 'CC' was exported here. + ==== /exportT.ts (0 errors) ==== export type T = number; @@ -45,4 +57,7 @@ declare module "baz" { export { T } from "foo"; // Also allowed. } + +==== /reExportValueAsTypeOnly.ts (0 errors) ==== + export type { C } from "./exportValue"; \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesReExportType.js b/tests/baselines/reference/isolatedModulesReExportType.js index 9908e6701dffe..2e3828fcfbb8d 100644 --- a/tests/baselines/reference/isolatedModulesReExportType.js +++ b/tests/baselines/reference/isolatedModulesReExportType.js @@ -21,6 +21,9 @@ declare module "baz" { export { T } from "foo"; // Also allowed. } +//// [reExportValueAsTypeOnly.ts] +export type { C } from "./exportValue"; + //// [user.ts] // Error, can't re-export something that's only a type. export { T } from "./exportT"; @@ -39,6 +42,14 @@ export type T3 = T; // Error, not clear (to an isolated module) whether `T4` is a type. import { T } from "./exportT"; export { T as T4 }; + +// Ok, type-only import indicates that the export can be elided. +import type { T as TT } from "./exportT"; +export { TT }; + +// Error, type-only declaration is in a different file. +import { C as CC } from "./reExportValueAsTypeOnly"; +export { CC }; //// [exportT.js] @@ -57,6 +68,9 @@ var C = /** @class */ (function () { return C; }()); exports.C = C; +//// [reExportValueAsTypeOnly.js] +"use strict"; +exports.__esModule = true; //// [user.js] "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { diff --git a/tests/baselines/reference/isolatedModulesReExportType.symbols b/tests/baselines/reference/isolatedModulesReExportType.symbols index b64f0cae4626a..e52acba684931 100644 --- a/tests/baselines/reference/isolatedModulesReExportType.symbols +++ b/tests/baselines/reference/isolatedModulesReExportType.symbols @@ -30,6 +30,22 @@ export { T as T4 }; >T : Symbol(T, Decl(user.ts, 15, 8)) >T4 : Symbol(T4, Decl(user.ts, 16, 8)) +// Ok, type-only import indicates that the export can be elided. +import type { T as TT } from "./exportT"; +>T : Symbol(NS.T, Decl(exportT.ts, 0, 0)) +>TT : Symbol(TT, Decl(user.ts, 19, 13)) + +export { TT }; +>TT : Symbol(TT, Decl(user.ts, 20, 8)) + +// Error, type-only declaration is in a different file. +import { C as CC } from "./reExportValueAsTypeOnly"; +>C : Symbol(C, Decl(reExportValueAsTypeOnly.ts, 0, 13)) +>CC : Symbol(CC, Decl(user.ts, 23, 8)) + +export { CC }; +>CC : Symbol(CC, Decl(user.ts, 24, 8)) + === /exportT.ts === export type T = number; >T : Symbol(T, Decl(exportT.ts, 0, 0)) @@ -45,3 +61,7 @@ declare type T = number; export = T; >T : Symbol(T, Decl(exportEqualsT.ts, 0, 0)) +=== /reExportValueAsTypeOnly.ts === +export type { C } from "./exportValue"; +>C : Symbol(C, Decl(reExportValueAsTypeOnly.ts, 0, 13)) + diff --git a/tests/baselines/reference/isolatedModulesReExportType.types b/tests/baselines/reference/isolatedModulesReExportType.types index 55c4cdfb7b778..370853c76aee5 100644 --- a/tests/baselines/reference/isolatedModulesReExportType.types +++ b/tests/baselines/reference/isolatedModulesReExportType.types @@ -8,7 +8,7 @@ export import T2 = require("./exportEqualsT"); // OK, has a value side export { C } from "./exportValue"; ->C : typeof import("/exportValue").C +>C : typeof CC // OK, even though the namespace it exports is only types. import * as NS from "./exportT"; @@ -29,6 +29,22 @@ export { T as T4 }; >T : any >T4 : any +// Ok, type-only import indicates that the export can be elided. +import type { T as TT } from "./exportT"; +>T : any +>TT : number + +export { TT }; +>TT : any + +// Error, type-only declaration is in a different file. +import { C as CC } from "./reExportValueAsTypeOnly"; +>C : typeof CC +>CC : typeof CC + +export { CC }; +>CC : typeof CC + === /exportT.ts === export type T = number; >T : number @@ -44,3 +60,7 @@ declare type T = number; export = T; >T : number +=== /reExportValueAsTypeOnly.ts === +export type { C } from "./exportValue"; +>C : import("/exportValue").C + diff --git a/tests/cases/compiler/isolatedModulesReExportType.ts b/tests/cases/compiler/isolatedModulesReExportType.ts index 6d82fd3f180d1..8bb10bbf22931 100644 --- a/tests/cases/compiler/isolatedModulesReExportType.ts +++ b/tests/cases/compiler/isolatedModulesReExportType.ts @@ -21,6 +21,9 @@ declare module "baz" { export { T } from "foo"; // Also allowed. } +// @Filename: /reExportValueAsTypeOnly.ts +export type { C } from "./exportValue"; + // @Filename: /user.ts // Error, can't re-export something that's only a type. export { T } from "./exportT"; @@ -39,3 +42,11 @@ export type T3 = T; // Error, not clear (to an isolated module) whether `T4` is a type. import { T } from "./exportT"; export { T as T4 }; + +// Ok, type-only import indicates that the export can be elided. +import type { T as TT } from "./exportT"; +export { TT }; + +// Error, type-only declaration is in a different file. +import { C as CC } from "./reExportValueAsTypeOnly"; +export { CC }; diff --git a/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_errors.ts b/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_errors.ts new file mode 100644 index 0000000000000..fcfcb70ea9b8f --- /dev/null +++ b/tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_errors.ts @@ -0,0 +1,46 @@ +// @importsNotUsedAsValues: preserve-exact +// @module: esnext + +// @Filename: a.ts +export type A = {}; +export type { A as default }; + +// @Filename: b.ts +class B {}; +export type { B, B as default }; + +// @Filename: c.ts +import DefaultA from "./a"; +import { A } from "./a"; +import DefaultB from "./b"; +import { B } from "./b"; + +// @Filename: c.fixed.ts +import type DefaultA from "./a"; +import type { A } from "./a"; +import type DefaultB from "./b"; +import type { B } from "./b"; + +// @Filename: d.ts +export { A as AA } from "./a"; +export { B as BB } from "./b"; + +// @Filename: d.fixed.ts +export type { A as AA } from "./a"; +export type { B as BB } from "./b"; + +// @Filename: e.ts +import { AA, BB } from "./d"; + +// @Filename: e.fixed.ts +import type { AA, BB } from "./d"; + +// @Filename: f.ts +import type { A } from "./a"; +import type { B } from "./b"; +export { A, B as BB }; + +// @Filename: f.fixed.ts +import type { A } from "./a"; +import type { B } from "./b"; +export type { A, B as BB }; From e6df1e5e5f4a73fc93000af51e5deb860992dd7f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 17 May 2021 17:21:22 -0700 Subject: [PATCH 5/6] Improve diagnostics wording --- src/compiler/checker.ts | 6 +++--- src/compiler/diagnosticMessages.json | 8 ++++---- src/compiler/program.ts | 2 +- ...dAsValues_preserve-exact_errors.errors.txt | 20 +++++++++---------- ...eserve-exact_module(module=amd).errors.txt | 4 ++-- ...e-exact_module(module=commonjs).errors.txt | 4 ++-- ...rve-exact_module(module=system).errors.txt | 4 ++-- .../isolatedModulesReExportType.errors.txt | 4 ++-- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2c6a6d1076fd4..e89ca27d2de19 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -38095,7 +38095,7 @@ namespace ts { if (compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.PreserveExact) { const message = isType ? Diagnostics._0_is_a_type_and_must_be_imported_with_a_type_only_import_when_importsNotUsedAsValues_is_set_to_preserve_exact - : Diagnostics._0_resolves_to_a_type_only_reference_and_must_be_imported_with_a_type_only_import_when_importsNotUsedAsValues_is_set_to_preserve_exact; + : Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_imported_with_a_type_only_import_when_importsNotUsedAsValues_is_set_to_preserve_exact; const name = idText(node.kind === SyntaxKind.ImportSpecifier ? node.propertyName || node.name : node.name!); addTypeOnlyDeclarationRelatedInfo( error(node, message, name), @@ -38119,9 +38119,9 @@ namespace ts { } const message = compilerOptions.isolatedModules && isType ? Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type : - compilerOptions.isolatedModules && !isType ? Diagnostics._0_resolves_to_a_type_only_reference_and_must_be_re_exported_with_a_type_only_re_export_when_isolatedModules_is_enabled : + compilerOptions.isolatedModules && !isType ? Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_re_exported_with_a_type_only_re_export_when_isolatedModules_is_enabled : isType ? Diagnostics._0_is_a_type_and_must_be_re_exported_with_a_type_only_re_export_when_importsNotUsedAsValues_is_set_to_preserve_exact : - Diagnostics._0_resolves_to_a_type_only_reference_and_must_be_re_exported_with_a_type_only_re_export_when_importsNotUsedAsValues_is_set_to_preserve_exact; + Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_re_exported_with_a_type_only_re_export_when_importsNotUsedAsValues_is_set_to_preserve_exact; const name = idText(node.propertyName || node.name); addTypeOnlyDeclarationRelatedInfo( error(node, message, name), diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e8232cd2a7d47..579dfc851918a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1372,15 +1372,15 @@ "category": "Error", "code": 1435 }, - "'{0}' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'.": { + "'{0}' resolves to a type-only declaration and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'.": { "category": "Error", "code": 1436 }, - "'{0}' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'.": { + "'{0}' resolves to a type-only declaration and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'.": { "category": "Error", "code": 1437 }, - "'{0}' resolves to a type-only reference and must be re-exported with a type-only re-export when 'isolatedModules' is enabled.": { + "'{0}' resolves to a type-only declaration and must be re-exported with a type-only re-export when 'isolatedModules' is enabled.": { "category": "Error", "code": 1438 }, @@ -3962,7 +3962,7 @@ "category": "Error", "code": 5094 }, - "Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later.": { + "Option 'importsNotUsedAsValues' may be set to 'preserve-exact' only when 'module' is set to 'es2015' or later.": { "category": "Error", "code": 5095 }, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index c7af1680fe108..0a0fc2a226bf5 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3296,7 +3296,7 @@ namespace ts { } if (options.importsNotUsedAsValues === ImportsNotUsedAsValues.PreserveExact && getEmitModuleKind(options) < ModuleKind.ES2015) { - createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_importsNotUsedAsValues_may_only_be_set_to_preserve_exact_when_module_is_set_to_es2015_or_later); + createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_importsNotUsedAsValues_may_be_set_to_preserve_exact_only_when_module_is_set_to_es2015_or_later); } // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.errors.txt index 52342ce13a8e9..22e14296a4b16 100644 --- a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.errors.txt +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_errors.errors.txt @@ -1,13 +1,13 @@ tests/cases/conformance/externalModules/typeOnly/c.ts(1,8): error TS1434: 'DefaultA' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. tests/cases/conformance/externalModules/typeOnly/c.ts(2,10): error TS1434: 'A' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. -tests/cases/conformance/externalModules/typeOnly/c.ts(3,8): error TS1436: 'DefaultB' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. -tests/cases/conformance/externalModules/typeOnly/c.ts(4,10): error TS1436: 'B' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/c.ts(3,8): error TS1436: 'DefaultB' resolves to a type-only declaration and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/c.ts(4,10): error TS1436: 'B' resolves to a type-only declaration and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. tests/cases/conformance/externalModules/typeOnly/d.ts(1,10): error TS1435: 'A' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. -tests/cases/conformance/externalModules/typeOnly/d.ts(2,10): error TS1437: 'B' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/d.ts(2,10): error TS1437: 'B' resolves to a type-only declaration and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. tests/cases/conformance/externalModules/typeOnly/e.ts(1,10): error TS1434: 'AA' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. -tests/cases/conformance/externalModules/typeOnly/e.ts(1,14): error TS1436: 'BB' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/e.ts(1,14): error TS1436: 'BB' resolves to a type-only declaration and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. tests/cases/conformance/externalModules/typeOnly/f.ts(3,10): error TS1435: 'A' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. -tests/cases/conformance/externalModules/typeOnly/f.ts(3,13): error TS1437: 'B' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +tests/cases/conformance/externalModules/typeOnly/f.ts(3,13): error TS1437: 'B' resolves to a type-only declaration and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. ==== tests/cases/conformance/externalModules/typeOnly/a.ts (0 errors) ==== @@ -27,11 +27,11 @@ tests/cases/conformance/externalModules/typeOnly/f.ts(3,13): error TS1437: 'B' r !!! error TS1434: 'A' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. import DefaultB from "./b"; ~~~~~~~~ -!!! error TS1436: 'DefaultB' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! error TS1436: 'DefaultB' resolves to a type-only declaration and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. !!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:18: 'DefaultB' was exported here. import { B } from "./b"; ~ -!!! error TS1436: 'B' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! error TS1436: 'B' resolves to a type-only declaration and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. !!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:15: 'B' was exported here. ==== tests/cases/conformance/externalModules/typeOnly/c.fixed.ts (0 errors) ==== @@ -46,7 +46,7 @@ tests/cases/conformance/externalModules/typeOnly/f.ts(3,13): error TS1437: 'B' r !!! error TS1435: 'A' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. export { B as BB } from "./b"; ~~~~~~~ -!!! error TS1437: 'B' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! error TS1437: 'B' resolves to a type-only declaration and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. !!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:15: 'B' was exported here. ==== tests/cases/conformance/externalModules/typeOnly/d.fixed.ts (0 errors) ==== @@ -58,7 +58,7 @@ tests/cases/conformance/externalModules/typeOnly/f.ts(3,13): error TS1437: 'B' r ~~ !!! error TS1434: 'AA' is a type and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. ~~ -!!! error TS1436: 'BB' resolves to a type-only reference and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! error TS1436: 'BB' resolves to a type-only declaration and must be imported with a type-only import when 'importsNotUsedAsValues' is set to 'preserve-exact'. !!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:15: 'BB' was exported here. ==== tests/cases/conformance/externalModules/typeOnly/e.fixed.ts (0 errors) ==== @@ -71,7 +71,7 @@ tests/cases/conformance/externalModules/typeOnly/f.ts(3,13): error TS1437: 'B' r ~ !!! error TS1435: 'A' is a type and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. ~~~~~~~ -!!! error TS1437: 'B' resolves to a type-only reference and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. +!!! error TS1437: 'B' resolves to a type-only declaration and must be re-exported with a type-only re-export when 'importsNotUsedAsValues' is set to 'preserve-exact'. !!! related TS1376 tests/cases/conformance/externalModules/typeOnly/f.ts:2:15: 'B' was imported here. ==== tests/cases/conformance/externalModules/typeOnly/f.fixed.ts (0 errors) ==== diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).errors.txt index 78cda02c61432..b52a3b9677bff 100644 --- a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).errors.txt +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=amd).errors.txt @@ -1,7 +1,7 @@ -error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +error TS5095: Option 'importsNotUsedAsValues' may be set to 'preserve-exact' only when 'module' is set to 'es2015' or later. -!!! error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +!!! error TS5095: Option 'importsNotUsedAsValues' may be set to 'preserve-exact' only when 'module' is set to 'es2015' or later. ==== tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts (0 errors) ==== export {}; \ No newline at end of file diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).errors.txt index 78cda02c61432..b52a3b9677bff 100644 --- a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).errors.txt +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=commonjs).errors.txt @@ -1,7 +1,7 @@ -error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +error TS5095: Option 'importsNotUsedAsValues' may be set to 'preserve-exact' only when 'module' is set to 'es2015' or later. -!!! error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +!!! error TS5095: Option 'importsNotUsedAsValues' may be set to 'preserve-exact' only when 'module' is set to 'es2015' or later. ==== tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts (0 errors) ==== export {}; \ No newline at end of file diff --git a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).errors.txt b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).errors.txt index 78cda02c61432..b52a3b9677bff 100644 --- a/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).errors.txt +++ b/tests/baselines/reference/importsNotUsedAsValues_preserve-exact_module(module=system).errors.txt @@ -1,7 +1,7 @@ -error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +error TS5095: Option 'importsNotUsedAsValues' may be set to 'preserve-exact' only when 'module' is set to 'es2015' or later. -!!! error TS5095: Option 'importsNotUsedAsValues' may only be set to 'preserve-exact' when 'module' is set to 'es2015' or later. +!!! error TS5095: Option 'importsNotUsedAsValues' may be set to 'preserve-exact' only when 'module' is set to 'es2015' or later. ==== tests/cases/conformance/externalModules/typeOnly/importsNotUsedAsValues_preserve-exact_module.ts (0 errors) ==== export {}; \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesReExportType.errors.txt b/tests/baselines/reference/isolatedModulesReExportType.errors.txt index 0b4b3df52077c..6fa10e49d3520 100644 --- a/tests/baselines/reference/isolatedModulesReExportType.errors.txt +++ b/tests/baselines/reference/isolatedModulesReExportType.errors.txt @@ -1,6 +1,6 @@ /user.ts(2,10): error TS1205: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'. /user.ts(17,10): error TS1205: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'. -/user.ts(25,10): error TS1438: 'CC' resolves to a type-only reference and must be re-exported with a type-only re-export when 'isolatedModules' is enabled. +/user.ts(25,10): error TS1438: 'CC' resolves to a type-only declaration and must be re-exported with a type-only re-export when 'isolatedModules' is enabled. ==== /user.ts (3 errors) ==== @@ -34,7 +34,7 @@ import { C as CC } from "./reExportValueAsTypeOnly"; export { CC }; ~~ -!!! error TS1438: 'CC' resolves to a type-only reference and must be re-exported with a type-only re-export when 'isolatedModules' is enabled. +!!! error TS1438: 'CC' resolves to a type-only declaration and must be re-exported with a type-only re-export when 'isolatedModules' is enabled. !!! related TS1377 /reExportValueAsTypeOnly.ts:1:15: 'CC' was exported here. ==== /exportT.ts (0 errors) ==== From 126069dd938f9c8d25779797470643658c5b0d79 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 17 May 2021 17:40:13 -0700 Subject: [PATCH 6/6] Update API baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 3 ++- tests/baselines/reference/api/typescript.d.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e94b1da823f34..073b62909746f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2946,7 +2946,8 @@ declare namespace ts { export enum ImportsNotUsedAsValues { Remove = 0, Preserve = 1, - Error = 2 + Error = 2, + PreserveExact = 3 } export enum NewLineKind { CarriageReturnLineFeed = 0, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 7b8a24ba088b4..206dd09a2b39b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2946,7 +2946,8 @@ declare namespace ts { export enum ImportsNotUsedAsValues { Remove = 0, Preserve = 1, - Error = 2 + Error = 2, + PreserveExact = 3 } export enum NewLineKind { CarriageReturnLineFeed = 0,