Add --preserveValueImports (#44619)

* Add compiler option

* Require es2015+

* Do not elide any imports or exports in preserve-exact

* Add errors for writing imports/exports that reference elided names

* Improve diagnostics wording

* Update API baselines

* Redo as noEraslingImportedNames

* Update option category

* Update baselines

* Lint

* Fix up transformer comments

* Fix errors from merge

* Update other error code baseline

* Rename to "preserveValueImports"

* Clean up, reword diagnostics

* Update API baselines

* Update other baseline affected by error message reword

* Update tsconfig baselines

* Add debug assertion instead of !
This commit is contained in:
Andrew Branch
2021-09-08 16:30:22 -07:00
committed by GitHub
parent b9eeb74f37
commit 8610ff5ebe
55 changed files with 1367 additions and 40 deletions
+62 -15
View File
@@ -2198,17 +2198,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
@@ -38813,13 +38821,49 @@ 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)
&& !isTypeOnlyImportOrExportDeclaration(node)
&& !(node.flags & NodeFlags.Ambient)) {
error(node, Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type);
const typeOnlyAlias = getTypeOnlyAliasDeclaration(symbol);
const isType = !(target.flags & SymbolFlags.Value);
if (isType || typeOnlyAlias) {
switch (node.kind) {
case SyntaxKind.ImportClause:
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ImportEqualsDeclaration: {
if (compilerOptions.preserveValueImports) {
Debug.assertIsDefined(node.name, "An ImportClause with a symbol should have a name");
const message = isType
? Diagnostics._0_is_a_type_and_must_be_imported_using_a_type_only_import_when_preserveValueImports_and_isolatedModules_are_both_enabled
: Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_imported_using_a_type_only_import_when_preserveValueImports_and_isolatedModules_are_both_enabled;
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.
// The exception is that `import type { A } from './a'; export { A }` is allowed
// because single-file analysis can determine that the export should be dropped.
if (getSourceFileOfNode(typeOnlyAlias) !== getSourceFileOfNode(node)) {
const message = isType
? Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type
: Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_re_exported_using_a_type_only_re_export_when_isolatedModules_is_enabled;
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))) {
@@ -40600,13 +40644,13 @@ namespace ts {
function isValueAliasDeclaration(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.ImportEqualsDeclaration:
return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol);
return isAliasResolvedToValue(getSymbolOfNode(node));
case SyntaxKind.ImportClause:
case SyntaxKind.NamespaceImport:
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier:
const symbol = getSymbolOfNode(node) || unknownSymbol;
return isAliasResolvedToValue(symbol) && !getTypeOnlyAliasDeclaration(symbol);
const symbol = getSymbolOfNode(node);
return !!symbol && isAliasResolvedToValue(symbol) && !getTypeOnlyAliasDeclaration(symbol);
case SyntaxKind.ExportDeclaration:
const exportClause = (node as ExportDeclaration).exportClause;
return !!exportClause && (
@@ -40615,7 +40659,7 @@ namespace ts {
);
case SyntaxKind.ExportAssignment:
return (node as ExportAssignment).expression && (node as ExportAssignment).expression.kind === SyntaxKind.Identifier ?
isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) :
isAliasResolvedToValue(getSymbolOfNode(node)) :
true;
}
return false;
@@ -40632,7 +40676,10 @@ namespace ts {
return isValue && node.moduleReference && !nodeIsMissing(node.moduleReference);
}
function isAliasResolvedToValue(symbol: Symbol): boolean {
function isAliasResolvedToValue(symbol: Symbol | undefined): boolean {
if (!symbol) {
return false;
}
const target = resolveAlias(symbol);
if (target === unknownSymbol) {
return true;
+9 -1
View File
@@ -571,7 +571,7 @@ namespace ts {
type: new Map(getEntries({
remove: ImportsNotUsedAsValues.Remove,
preserve: ImportsNotUsedAsValues.Preserve,
error: ImportsNotUsedAsValues.Error
error: ImportsNotUsedAsValues.Error,
})),
affectsEmit: true,
affectsSemanticDiagnostics: true,
@@ -1169,6 +1169,14 @@ namespace ts {
description: Diagnostics.Emit_ECMAScript_standard_compliant_class_fields,
defaultValueDescription: Diagnostics.true_for_ES2022_and_above_including_ESNext
},
{
name: "preserveValueImports",
type: "boolean",
affectsEmit: true,
category: Diagnostics.Emit,
description: Diagnostics.Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed,
},
{
name: "keyofStringsOnly",
type: "boolean",
+20
View File
@@ -1372,6 +1372,22 @@
"category": "Error",
"code": 1443
},
"'{0}' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.": {
"category": "Error",
"code": 1444
},
"'{0}' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.": {
"category": "Error",
"code": 1446
},
"'{0}' resolves to a type-only declaration and must be re-exported using a type-only re-export when 'isolatedModules' is enabled.": {
"category": "Error",
"code": 1448
},
"Preserve unused imported values in the JavaScript output that would otherwise be removed.": {
"category": "Message",
"code": 1449
},
"The types of '{0}' are incompatible between these types.": {
"category": "Error",
@@ -3910,6 +3926,10 @@
"category": "Error",
"code": 5094
},
"Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.": {
"category": "Error",
"code": 5095
},
"Generates a sourcemap for each corresponding '.d.ts' file.": {
"category": "Message",
+7 -3
View File
@@ -3305,6 +3305,10 @@ namespace ts {
}
}
if (options.preserveValueImports && getEmitModuleKind(options) < ModuleKind.ES2015) {
createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_preserveValueImports_can_only_be_used_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();
@@ -3575,7 +3579,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);
}
@@ -3590,7 +3594,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);
@@ -3616,7 +3620,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));
+17 -15
View File
@@ -2791,7 +2791,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 type-only or if it has an import clause that may be elided.
*
* @param node The import declaration node.
*/
@@ -2821,29 +2821,27 @@ namespace ts {
}
/**
* Visits an import clause, eliding it if it is not referenced.
* Visits an import clause, eliding it if its `name` and `namedBindings` may both be elided.
*
* @param node The import clause node.
*/
function visitImportClause(node: ImportClause): VisitResult<ImportClause> {
if (node.isTypeOnly) {
return undefined;
}
Debug.assert(!node.isTypeOnly);
// Elide the import clause if we elide both its name and its named bindings.
const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
const name = shouldEmitAliasDeclaration(node) ? node.name : undefined;
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings);
return (name || namedBindings) ? factory.updateImportClause(node, /*isTypeOnly*/ false, name, namedBindings) : undefined;
}
/**
* Visits named import bindings, eliding it if it is not referenced.
* Visits named import bindings, eliding them if their targets, their references, and the compilation settings allow.
*
* @param node The named import bindings node.
*/
function visitNamedImportBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> {
if (node.kind === SyntaxKind.NamespaceImport) {
// Elide a namespace import if it is not referenced.
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
return shouldEmitAliasDeclaration(node) ? node : undefined;
}
else {
// Elide named imports if all of its import specifiers are elided.
@@ -2853,13 +2851,12 @@ namespace ts {
}
/**
* Visits an import specifier, eliding it if it is not referenced.
* Visits an import specifier, eliding it if its target, its references, and the compilation settings allow.
*
* @param node The import specifier node.
*/
function visitImportSpecifier(node: ImportSpecifier): VisitResult<ImportSpecifier> {
// Elide an import specifier if it is not referenced.
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
return shouldEmitAliasDeclaration(node) ? node : undefined;
}
/**
@@ -2876,8 +2873,7 @@ namespace ts {
}
/**
* Visits an export declaration, eliding it if it does not contain a clause that resolves
* to a value.
* Visits an export declaration, eliding it if it does not contain a clause that resolves to a value.
*
* @param node The export declaration node.
*/
@@ -2950,7 +2946,7 @@ namespace ts {
// preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
// - current file is not external module
// - import declaration is top level and target is value imported by entity name
return resolver.isReferencedAliasDeclaration(node)
return shouldEmitAliasDeclaration(node)
|| (!isExternalModule(currentSourceFile)
&& resolver.isTopLevelValueImportEqualsWithEntityName(node));
}
@@ -2967,7 +2963,7 @@ namespace ts {
}
if (isExternalModuleImportEqualsDeclaration(node)) {
const isReferenced = resolver.isReferencedAliasDeclaration(node);
const isReferenced = shouldEmitAliasDeclaration(node);
// If the alias is unreferenced but we want to keep the import, replace with 'import "mod"'.
if (!isReferenced && compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve) {
return setOriginalNode(
@@ -3358,5 +3354,11 @@ namespace ts {
return isPropertyAccessExpression(node) || isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined;
}
function shouldEmitAliasDeclaration(node: Node): boolean {
return compilerOptions.preserveValueImports
? resolver.isValueAliasDeclaration(node)
: resolver.isReferencedAliasDeclaration(node);
}
}
}
+10 -1
View File
@@ -3109,6 +3109,14 @@ namespace ts {
| ImportOrExportSpecifier
;
export type TypeOnlyAliasDeclaration =
| ImportClause & { readonly isTypeOnly: true, readonly name: Identifier }
| ImportEqualsDeclaration & { readonly isTypeOnly: true }
| NamespaceImport & { readonly parent: ImportClause & { readonly isTypeOnly: true } }
| ImportSpecifier & { readonly parent: NamedImports & { readonly parent: ImportClause & { readonly isTypeOnly: true } } }
| ExportSpecifier & { readonly parent: NamedExports & { readonly parent: ExportDeclaration & { readonly isTypeOnly: true } } }
;
/**
* This is either an `export =` or an `export default` declaration.
* Unless `isExportEquals` is set, this node was parsed as an `export default`.
@@ -6057,6 +6065,7 @@ namespace ts {
preserveConstEnums?: boolean;
noImplicitOverride?: boolean;
preserveSymlinks?: boolean;
preserveValueImports?: boolean;
/* @internal */ preserveWatchOutput?: boolean;
project?: string;
/* @internal */ pretty?: boolean;
@@ -6150,7 +6159,7 @@ namespace ts {
export const enum ImportsNotUsedAsValues {
Remove,
Preserve,
Error
Error,
}
export const enum NewLineKind {
+1 -1
View File
@@ -1126,7 +1126,7 @@ namespace ts {
return isImportSpecifier(node) || isExportSpecifier(node);
}
export function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyCompatibleAliasDeclaration {
export function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyAliasDeclaration {
switch (node.kind) {
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier:
+24 -1
View File
@@ -1688,6 +1688,28 @@ declare namespace ts {
}
export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier;
export type TypeOnlyCompatibleAliasDeclaration = ImportClause | ImportEqualsDeclaration | NamespaceImport | ImportOrExportSpecifier;
export type TypeOnlyAliasDeclaration = ImportClause & {
readonly isTypeOnly: true;
readonly name: Identifier;
} | ImportEqualsDeclaration & {
readonly isTypeOnly: true;
} | NamespaceImport & {
readonly parent: ImportClause & {
readonly isTypeOnly: true;
};
} | ImportSpecifier & {
readonly parent: NamedImports & {
readonly parent: ImportClause & {
readonly isTypeOnly: true;
};
};
} | ExportSpecifier & {
readonly parent: NamedExports & {
readonly parent: ExportDeclaration & {
readonly isTypeOnly: true;
};
};
};
/**
* This is either an `export =` or an `export default` declaration.
* Unless `isExportEquals` is set, this node was parsed as an `export default`.
@@ -2904,6 +2926,7 @@ declare namespace ts {
preserveConstEnums?: boolean;
noImplicitOverride?: boolean;
preserveSymlinks?: boolean;
preserveValueImports?: boolean;
project?: string;
reactNamespace?: string;
jsxFactory?: string;
@@ -4321,7 +4344,7 @@ declare namespace ts {
function isTemplateLiteralToken(node: Node): node is TemplateLiteralToken;
function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail;
function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | ExportSpecifier;
function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyCompatibleAliasDeclaration;
function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyAliasDeclaration;
function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken;
function isModifier(node: Node): node is Modifier;
function isEntityName(node: Node): node is EntityName;
+24 -1
View File
@@ -1688,6 +1688,28 @@ declare namespace ts {
}
export type ImportOrExportSpecifier = ImportSpecifier | ExportSpecifier;
export type TypeOnlyCompatibleAliasDeclaration = ImportClause | ImportEqualsDeclaration | NamespaceImport | ImportOrExportSpecifier;
export type TypeOnlyAliasDeclaration = ImportClause & {
readonly isTypeOnly: true;
readonly name: Identifier;
} | ImportEqualsDeclaration & {
readonly isTypeOnly: true;
} | NamespaceImport & {
readonly parent: ImportClause & {
readonly isTypeOnly: true;
};
} | ImportSpecifier & {
readonly parent: NamedImports & {
readonly parent: ImportClause & {
readonly isTypeOnly: true;
};
};
} | ExportSpecifier & {
readonly parent: NamedExports & {
readonly parent: ExportDeclaration & {
readonly isTypeOnly: true;
};
};
};
/**
* This is either an `export =` or an `export default` declaration.
* Unless `isExportEquals` is set, this node was parsed as an `export default`.
@@ -2904,6 +2926,7 @@ declare namespace ts {
preserveConstEnums?: boolean;
noImplicitOverride?: boolean;
preserveSymlinks?: boolean;
preserveValueImports?: boolean;
project?: string;
reactNamespace?: string;
jsxFactory?: string;
@@ -4321,7 +4344,7 @@ declare namespace ts {
function isTemplateLiteralToken(node: Node): node is TemplateLiteralToken;
function isTemplateMiddleOrTemplateTail(node: Node): node is TemplateMiddle | TemplateTail;
function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | ExportSpecifier;
function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyCompatibleAliasDeclaration;
function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyAliasDeclaration;
function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken;
function isModifier(node: Node): node is Modifier;
function isEntityName(node: Node): node is EntityName;
@@ -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 TS1448: 'CC' resolves to a type-only declaration and must be re-exported using 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 TS1448: 'CC' resolves to a type-only declaration and must be re-exported using 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";
@@ -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) {
@@ -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))
@@ -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
@@ -0,0 +1,36 @@
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;
export interface D {}
==== tests/cases/conformance/externalModules/typeOnly/b.ts (0 errors) ====
import a, { b, c, D } 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;
@@ -0,0 +1,44 @@
//// [tests/cases/conformance/externalModules/typeOnly/preserveValueImports.ts] ////
//// [a.ts]
export default {};
export const b = 0;
export const c = 1;
export interface D {}
//// [b.ts]
import a, { b, c, D } 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;
@@ -0,0 +1,46 @@
=== 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))
export interface D {}
>D : Symbol(D, Decl(a.ts, 2, 19))
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
import a, { b, c, D } 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))
>D : Symbol(D, Decl(b.ts, 0, 17))
=== 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))
@@ -0,0 +1,50 @@
=== 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
export interface D {}
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
import a, { b, c, D } from "./a";
>a : {}
>b : 0
>c : 1
>D : any
=== 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
@@ -0,0 +1,39 @@
tests/cases/conformance/externalModules/typeOnly/b.ts(1,19): error TS1444: 'D' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
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;
export interface D {}
==== tests/cases/conformance/externalModules/typeOnly/b.ts (1 errors) ====
import a, { b, c, D } from "./a";
~
!!! error TS1444: 'D' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
==== 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;
@@ -0,0 +1,44 @@
//// [tests/cases/conformance/externalModules/typeOnly/preserveValueImports.ts] ////
//// [a.ts]
export default {};
export const b = 0;
export const c = 1;
export interface D {}
//// [b.ts]
import a, { b, c, D } 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;
@@ -0,0 +1,46 @@
=== 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))
export interface D {}
>D : Symbol(D, Decl(a.ts, 2, 19))
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
import a, { b, c, D } 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))
>D : Symbol(D, Decl(b.ts, 0, 17))
=== 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))
@@ -0,0 +1,50 @@
=== 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
export interface D {}
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
import a, { b, c, D } from "./a";
>a : {}
>b : 0
>c : 1
>D : any
=== 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
@@ -0,0 +1,73 @@
//// [tests/cases/conformance/externalModules/typeOnly/preserveValueImports_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]
export {};
//// [c.fixed.js]
export {};
//// [d.js]
export {};
//// [d.fixed.js]
export {};
//// [e.js]
export {};
//// [e.fixed.js]
export {};
//// [f.js]
export {};
//// [f.fixed.js]
export {};
@@ -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))
@@ -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
@@ -0,0 +1,74 @@
tests/cases/conformance/externalModules/typeOnly/c.ts(1,8): error TS1444: 'DefaultA' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
tests/cases/conformance/externalModules/typeOnly/c.ts(2,10): error TS1444: 'A' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
tests/cases/conformance/externalModules/typeOnly/c.ts(3,8): error TS1446: 'DefaultB' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
tests/cases/conformance/externalModules/typeOnly/c.ts(4,10): error TS1446: 'B' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
tests/cases/conformance/externalModules/typeOnly/d.ts(1,10): error TS1205: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
tests/cases/conformance/externalModules/typeOnly/d.ts(2,10): error TS1448: 'B' resolves to a type-only declaration and must be re-exported using a type-only re-export when 'isolatedModules' is enabled.
tests/cases/conformance/externalModules/typeOnly/e.ts(1,10): error TS1444: 'AA' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
tests/cases/conformance/externalModules/typeOnly/e.ts(1,14): error TS1446: 'BB' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
==== 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 TS1444: 'DefaultA' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
import { A } from "./a";
~
!!! error TS1444: 'A' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
import DefaultB from "./b";
~~~~~~~~
!!! error TS1446: 'DefaultB' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
!!! related TS1377 tests/cases/conformance/externalModules/typeOnly/b.ts:2:18: 'DefaultB' was exported here.
import { B } from "./b";
~
!!! error TS1446: 'B' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
!!! 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 TS1205: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
export { B as BB } from "./b";
~~~~~~~
!!! error TS1448: 'B' resolves to a type-only declaration and must be re-exported using a type-only re-export when 'isolatedModules' is enabled.
!!! 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 TS1444: 'AA' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
~~
!!! error TS1446: 'BB' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.
!!! 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 (0 errors) ====
import type { A } from "./a";
import type { B } from "./b";
export { A, B as BB };
==== 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 };
@@ -0,0 +1,73 @@
//// [tests/cases/conformance/externalModules/typeOnly/preserveValueImports_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]
export {};
//// [c.fixed.js]
export {};
//// [d.js]
export {};
//// [d.fixed.js]
export {};
//// [e.js]
export {};
//// [e.fixed.js]
export {};
//// [f.js]
export {};
//// [f.fixed.js]
export {};
@@ -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))
@@ -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
@@ -0,0 +1,7 @@
error TS5095: Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.
!!! error TS5095: Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.
==== tests/cases/conformance/externalModules/typeOnly/preserveValueImports_module.ts (0 errors) ====
export {};
@@ -0,0 +1,9 @@
//// [preserveValueImports_module.ts]
export {};
//// [preserveValueImports_module.js]
define(["require", "exports"], function (require, exports) {
"use strict";
exports.__esModule = true;
});
@@ -0,0 +1,7 @@
error TS5095: Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.
!!! error TS5095: Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.
==== tests/cases/conformance/externalModules/typeOnly/preserveValueImports_module.ts (0 errors) ====
export {};
@@ -0,0 +1,7 @@
//// [preserveValueImports_module.ts]
export {};
//// [preserveValueImports_module.js]
"use strict";
exports.__esModule = true;
@@ -0,0 +1,6 @@
//// [preserveValueImports_module.ts]
export {};
//// [preserveValueImports_module.js]
export {};
@@ -0,0 +1,7 @@
error TS5095: Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.
!!! error TS5095: Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.
==== tests/cases/conformance/externalModules/typeOnly/preserveValueImports_module.ts (0 errors) ====
export {};
@@ -0,0 +1,14 @@
//// [preserveValueImports_module.ts]
export {};
//// [preserveValueImports_module.js]
System.register([], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
return {
setters: [],
execute: function () {
}
};
});
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"preserveValueImports": true
}
}
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
"declarationDir": "lib", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -64,6 +64,7 @@
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -85,6 +85,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
"declarationDir": "decls", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -85,6 +85,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
"declarationDir": "decls", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -85,6 +85,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -85,6 +85,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -85,6 +85,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -85,6 +85,7 @@ interface Array<T> { length: number; [n: number]: T; }
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
@@ -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 };
@@ -0,0 +1,28 @@
// @preserveValueImports: true
// @isolatedModules: true,false
// @module: esnext
// @Filename: a.ts
export default {};
export const b = 0;
export const c = 1;
export interface D {}
// @Filename: b.ts
import a, { b, c, D } 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;
@@ -0,0 +1,47 @@
// @preserveValueImports: true
// @isolatedModules: true,false
// @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 };
@@ -0,0 +1,4 @@
// @preserveValueImports: true
// @module: amd,system,commonjs,es2015
// @noTypesAndSymbols: true
export {};