Fix type-only imports in interface 'extends' and import=/export= (#36496)

* Handle when files get checked in different orders

* Fix interface extends clause

* Fix import= something type only from a module

* Revert apparently unnecessary addition

* Revert "Revert apparently unnecessary addition"

This reverts commit 7444b0b72ea2e628ff414b675ef42723a6a7695d.

* Disallow `import = a.b.c` on anything with type-only imports

* Safety first

* Add test for TS Server single-file open

* Add big comment

* Extract error reporting function for import aliases

* Delete blank line

* Un-export, comment, and colocate some utils

* Combine 3 type-only marking function calls into one

* Add more export default tests
This commit is contained in:
Andrew Branch 2020-01-29 15:00:17 -08:00 committed by GitHub
parent aec732a898
commit 2fac535158
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1298 additions and 52 deletions

View File

@ -2221,9 +2221,30 @@ namespace ts {
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration, dontResolveAlias: boolean): Symbol | undefined {
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node)));
const immediate = resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node));
const resolved = resolveExternalModuleSymbol(immediate);
markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false);
return resolved;
}
const resolved = getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias);
checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node, resolved);
return resolved;
}
function checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node: ImportEqualsDeclaration, resolved: Symbol | undefined) {
if (markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false)) {
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(getSymbolOfNode(node))!;
const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
? Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type
: Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type;
const relatedMessage = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
? Diagnostics._0_was_exported_here
: Diagnostics._0_was_imported_here;
// Non-null assertion is safe because the optionality comes from ImportClause,
// but if an ImportClause was the typeOnlyDeclaration, it had to have a `name`.
const name = unescapeLeadingUnderscores(typeOnlyDeclaration.name!.escapedText);
addRelatedInfo(error(node.moduleReference, message), createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, name));
}
return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias);
}
function resolveExportByName(moduleSymbol: Symbol, name: __String, sourceNode: TypeOnlyCompatibleAliasDeclaration | undefined, dontResolveAlias: boolean) {
@ -2232,8 +2253,9 @@ namespace ts {
return getPropertyOfType(getTypeOfSymbol(exportValue), name);
}
const exportSymbol = moduleSymbol.exports!.get(name);
markSymbolOfAliasDeclarationIfResolvesToTypeOnly(sourceNode, exportSymbol);
return resolveSymbol(exportSymbol, dontResolveAlias);
const resolved = resolveSymbol(exportSymbol, dontResolveAlias);
markSymbolOfAliasDeclarationIfTypeOnly(sourceNode, exportSymbol, resolved, /*overwriteEmpty*/ false);
return resolved;
}
function isSyntacticDefault(node: Node) {
@ -2273,8 +2295,6 @@ namespace ts {
function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol | undefined {
const moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier);
markSymbolOfAliasDeclarationIfTypeOnly(node);
if (moduleSymbol) {
let exportDefaultSymbol: Symbol | undefined;
if (isShorthandAmbientModuleSymbol(moduleSymbol)) {
@ -2316,16 +2336,21 @@ namespace ts {
}
else if (hasSyntheticDefault) {
// per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present
return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
const resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false);
return resolved;
}
markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false);
return exportDefaultSymbol;
}
}
function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol | undefined {
const moduleSpecifier = node.parent.parent.moduleSpecifier;
markSymbolOfAliasDeclarationIfTypeOnly(node);
return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
const immediate = resolveExternalModuleName(node, moduleSpecifier);
const resolved = resolveESModuleSymbol(immediate, moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false);
return resolved;
}
function getTargetOfNamespaceExport(node: NamespaceExport, dontResolveAlias: boolean): Symbol | undefined {
@ -2371,8 +2396,9 @@ namespace ts {
if (symbol.flags & SymbolFlags.Module) {
const name = (specifier.propertyName ?? specifier.name).escapedText;
const exportSymbol = getExportsOfSymbol(symbol).get(name);
markSymbolOfAliasDeclarationIfResolvesToTypeOnly(specifier, exportSymbol);
return resolveSymbol(exportSymbol, dontResolveAlias);
const resolved = resolveSymbol(exportSymbol, dontResolveAlias);
markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false);
return resolved;
}
}
@ -2472,8 +2498,9 @@ namespace ts {
}
function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol | undefined {
markSymbolOfAliasDeclarationIfTypeOnly(node);
return getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias);
const resolved = getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias);
markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
return resolved;
}
function getTargetOfNamespaceExportDeclaration(node: NamespaceExportDeclaration, dontResolveAlias: boolean): Symbol {
@ -2481,15 +2508,18 @@ namespace ts {
}
function getTargetOfExportSpecifier(node: ExportSpecifier, meaning: SymbolFlags, dontResolveAlias?: boolean) {
markSymbolOfAliasDeclarationIfTypeOnly(node);
return node.parent.parent.moduleSpecifier ?
const resolved = node.parent.parent.moduleSpecifier ?
getExternalModuleMember(node.parent.parent, node, dontResolveAlias) :
resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias);
markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
return resolved;
}
function getTargetOfExportAssignment(node: ExportAssignment | BinaryExpression, dontResolveAlias: boolean): Symbol | undefined {
const expression = (isExportAssignment(node) ? node.expression : node.right) as EntityNameExpression | ClassExpression;
return getTargetOfAliasLikeExpression(expression, dontResolveAlias);
const resolved = getTargetOfAliasLikeExpression(expression, dontResolveAlias);
markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
return resolved;
}
function getTargetOfAliasLikeExpression(expression: Expression, dontResolveAlias: boolean) {
@ -2586,22 +2616,55 @@ namespace ts {
return links.target;
}
function markSymbolOfAliasDeclarationIfResolvesToTypeOnly(aliasDeclaration: TypeOnlyCompatibleAliasDeclaration | undefined, resolvesToSymbol: Symbol | undefined) {
if (!aliasDeclaration || !resolvesToSymbol) return;
/**
* Marks a symbol as type-only if its declaration is syntactically type-only.
* If it is not itself marked type-only, but resolves to a type-only alias
* somewhere in its resolution chain, save a reference to the type-only alias declaration
* so the alias _not_ marked type-only can be identified as _transitively_ type-only.
*
* This function is called on each alias declaration that could be type-only or resolve to
* another type-only alias during `resolveAlias`, so that later, when an alias is used in a
* JS-emitting expression, we can quickly determine if that symbol is effectively type-only
* and issue an error if so.
*
* @param aliasDeclaration The alias declaration not marked as type-only
* has already been marked as not resolving to a type-only alias. Used when recursively resolving qualified
* names of import aliases, e.g. `import C = a.b.C`. If namespace `a` is not found to be type-only, the
* import declaration will initially be marked as not resolving to a type-only symbol. But, namespace `b`
* must still be checked for a type-only marker, overwriting the previous negative result if found.
* @param immediateTarget The symbol to which the alias declaration immediately resolves
* @param finalTarget The symbol to which the alias declaration ultimately resolves
* @param overwriteEmpty Checks `resolvesToSymbol` for type-only declarations even if `aliasDeclaration`
*/
function markSymbolOfAliasDeclarationIfTypeOnly(
aliasDeclaration: Declaration | undefined,
immediateTarget: Symbol | undefined,
finalTarget: Symbol | undefined,
overwriteEmpty: boolean,
): boolean {
if (!aliasDeclaration) return false;
// If the declaration itself is type-only, mark it and return.
// No need to check what it resolves to.
const sourceSymbol = getSymbolOfNode(aliasDeclaration);
const links = getSymbolLinks(sourceSymbol);
if (links.typeOnlyDeclaration === undefined) {
const typeOnly = find(resolvesToSymbol.declarations, isTypeOnlyImportOrExportDeclaration);
links.typeOnlyDeclaration = typeOnly ?? getSymbolLinks(resolvesToSymbol).typeOnlyDeclaration ?? false;
if (isTypeOnlyImportOrExportDeclaration(aliasDeclaration)) {
const links = getSymbolLinks(sourceSymbol);
links.typeOnlyDeclaration = aliasDeclaration;
return true;
}
const links = getSymbolLinks(sourceSymbol);
return markSymbolOfAliasDeclarationIfTypeOnlyWorker(links, immediateTarget, overwriteEmpty)
|| markSymbolOfAliasDeclarationIfTypeOnlyWorker(links, finalTarget, overwriteEmpty);
}
function markSymbolOfAliasDeclarationIfTypeOnly(aliasDeclaration: TypeOnlyCompatibleAliasDeclaration) {
if (isTypeOnlyImportOrExportDeclaration(aliasDeclaration)) {
const symbol = getSymbolOfNode(aliasDeclaration);
const links = getSymbolLinks(symbol);
links.typeOnlyDeclaration = aliasDeclaration;
function markSymbolOfAliasDeclarationIfTypeOnlyWorker(aliasDeclarationLinks: SymbolLinks, target: Symbol | undefined, overwriteEmpty: boolean): boolean {
if (target && (aliasDeclarationLinks.typeOnlyDeclaration === undefined || overwriteEmpty && aliasDeclarationLinks.typeOnlyDeclaration === false)) {
const exportSymbol = target.exports?.get(InternalSymbolName.ExportEquals) ?? target;
const typeOnly = exportSymbol.declarations && find(exportSymbol.declarations, isTypeOnlyImportOrExportDeclaration);
aliasDeclarationLinks.typeOnlyDeclaration = typeOnly ?? getSymbolLinks(exportSymbol).typeOnlyDeclaration ?? false;
}
return !!aliasDeclarationLinks.typeOnlyDeclaration;
}
/** Indicates that a symbol directly or indirectly resolves to a type-only import or export. */
@ -2739,8 +2802,8 @@ namespace ts {
throw Debug.assertNever(name, "Unknown entity name kind.");
}
Debug.assert((getCheckFlags(symbol) & CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here.");
if (isIdentifier(name) && symbol.flags & SymbolFlags.Alias) {
markSymbolOfAliasDeclarationIfResolvesToTypeOnly(getTypeOnlyCompatibleAliasDeclarationFromName(name), symbol);
if (isEntityName(name) && (symbol.flags & SymbolFlags.Alias || name.parent.kind === SyntaxKind.ExportAssignment)) {
markSymbolOfAliasDeclarationIfTypeOnly(getAliasDeclarationFromName(name), symbol, /*finalTarget*/ undefined, /*overwriteEmpty*/ true);
}
return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
}

View File

@ -2011,4 +2011,4 @@ namespace ts {
}
}
}
}
}

View File

@ -1127,6 +1127,14 @@
"category": "Error",
"code": 1378
},
"An import alias cannot reference a declaration that was exported using 'export type'.": {
"category": "Error",
"code": 1379
},
"An import alias cannot reference a declaration that was imported using 'import type'.": {
"category": "Error",
"code": 1380
},
"The types of '{0}' are incompatible between these types.": {
"category": "Error",

View File

@ -1778,25 +1778,6 @@ namespace ts {
return node.kind === SyntaxKind.TypeQuery;
}
export function isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(node: Node) {
while (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) {
node = node.parent;
}
if (node.kind !== SyntaxKind.ComputedPropertyName) {
return false;
}
if (hasModifier(node.parent, ModifierFlags.Abstract)) {
return true;
}
const containerKind = node.parent.parent.kind;
return containerKind === SyntaxKind.InterfaceDeclaration || containerKind === SyntaxKind.TypeLiteral;
}
export function isFirstIdentifierOfImplementsClause(node: Node) {
return node.parent?.parent?.parent?.kind === SyntaxKind.HeritageClause
&& (node.parent.parent.parent as HeritageClause).token === SyntaxKind.ImplementsKeyword;
}
export function isExternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration & { moduleReference: ExternalModuleReference } {
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference;
}
@ -2738,13 +2719,47 @@ namespace ts {
return false;
}
export function getTypeOnlyCompatibleAliasDeclarationFromName(node: Identifier): TypeOnlyCompatibleAliasDeclaration | undefined {
// An alias symbol is created by one of the following declarations:
// import <symbol> = ...
// import <symbol> from ...
// import * as <symbol> from ...
// import { x as <symbol> } from ...
// export { x as <symbol> } from ...
// export * as ns <symbol> from ...
// export = <EntityNameExpression>
// export default <EntityNameExpression>
// module.exports = <EntityNameExpression>
// {<Identifier>}
// {name: <EntityNameExpression>}
export function isAliasSymbolDeclaration(node: Node): boolean {
return node.kind === SyntaxKind.ImportEqualsDeclaration ||
node.kind === SyntaxKind.NamespaceExportDeclaration ||
node.kind === SyntaxKind.ImportClause && !!(<ImportClause>node).name ||
node.kind === SyntaxKind.NamespaceImport ||
node.kind === SyntaxKind.NamespaceExport ||
node.kind === SyntaxKind.ImportSpecifier ||
node.kind === SyntaxKind.ExportSpecifier ||
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node) ||
isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node) ||
isPropertyAccessExpression(node) && isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === SyntaxKind.EqualsToken && isAliasableExpression(node.parent.right) ||
node.kind === SyntaxKind.ShorthandPropertyAssignment ||
node.kind === SyntaxKind.PropertyAssignment && isAliasableExpression((node as PropertyAssignment).initializer);
}
export function getAliasDeclarationFromName(node: EntityName): Declaration | undefined {
switch (node.parent.kind) {
case SyntaxKind.ImportClause:
case SyntaxKind.ImportSpecifier:
case SyntaxKind.NamespaceImport:
case SyntaxKind.ExportSpecifier:
return node.parent as TypeOnlyCompatibleAliasDeclaration;
case SyntaxKind.ExportAssignment:
case SyntaxKind.ImportEqualsDeclaration:
return node.parent as Declaration;
case SyntaxKind.QualifiedName:
do {
node = node.parent as QualifiedName;
} while (node.parent.kind === SyntaxKind.QualifiedName);
return getAliasDeclarationFromName(node);
}
}
@ -6116,8 +6131,29 @@ namespace ts {
export function isValidTypeOnlyAliasUseSite(useSite: Node): boolean {
return !!(useSite.flags & NodeFlags.Ambient)
|| isPartOfTypeQuery(useSite)
|| isFirstIdentifierOfImplementsClause(useSite)
|| isFirstIdentifierOfNonEmittingHeritageClause(useSite)
|| isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite)
|| !isExpressionNode(useSite);
}
function isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(node: Node) {
while (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) {
node = node.parent;
}
if (node.kind !== SyntaxKind.ComputedPropertyName) {
return false;
}
if (hasModifier(node.parent, ModifierFlags.Abstract)) {
return true;
}
const containerKind = node.parent.parent.kind;
return containerKind === SyntaxKind.InterfaceDeclaration || containerKind === SyntaxKind.TypeLiteral;
}
/** Returns true for the first identifier of 1) an `implements` clause, and 2) an `extends` clause of an interface. */
function isFirstIdentifierOfNonEmittingHeritageClause(node: Node): boolean {
// Number of parents to climb from identifier is 2 for `implements I`, 3 for `implements x.I`
const heritageClause = tryCast(node.parent.parent, isHeritageClause) ?? tryCast(node.parent.parent?.parent, isHeritageClause);
return heritageClause?.token === SyntaxKind.ImplementsKeyword || heritageClause?.parent.kind === SyntaxKind.InterfaceDeclaration;
}
}

View File

@ -186,6 +186,7 @@
"unittests/tsserver/textStorage.ts",
"unittests/tsserver/telemetry.ts",
"unittests/tsserver/typeAquisition.ts",
"unittests/tsserver/typeOnlyImportChains.ts",
"unittests/tsserver/typeReferenceDirectives.ts",
"unittests/tsserver/typingsInstaller.ts",
"unittests/tsserver/untitledFiles.ts",

View File

@ -0,0 +1,104 @@
namespace ts.projectSystem {
describe("unittests:: tsserver:: typeOnlyImportChains", () => {
it("named export -> type-only namespace import -> named export -> named import", () => {
const a = {
path: "/a.ts",
content: "export class A {}"
};
const b = {
path: "/b.ts",
content: "import type * as a from './a'; export { a };"
};
const c = {
path: "/c.ts",
content: "import { a } from './b'; new a.A();"
};
assertUsageError([a, b, c], c);
});
it("named export -> type-only named import -> named export -> named import", () => {
const a = {
path: "/a.ts",
content: "export class A {}"
};
const b = {
path: "/b.ts",
content: "import type { A } from './a'; export { A };"
};
const c = {
path: "/c.ts",
content: "import { A } from './b'; new A();"
};
assertUsageError([a, b, c], c);
});
it("named export -> type-only namespace import -> export equals -> import equals", () => {
const a = {
path: "/a.ts",
content: "export class A {}"
};
const b = {
path: "/b.ts",
content: "import type * as a from './a'; export = a;"
};
const c = {
path: "/c.ts",
content: "import a = require('./b'); new a.A();"
};
assertUsageError([a, b, c], c);
});
it("named export -> type-only namespace import -> export default -> import default", () => {
const a = {
path: "/a.ts",
content: "export class A {}"
};
const b = {
path: "/b.ts",
content: "import type * as a from './a'; export default a;"
};
const c = {
path: "/c.ts",
content: "import a from './b'; new a.A();"
};
assertUsageError([a, b, c], c);
});
it("export default -> type-only import default -> export default -> import default", () => {
const a = {
path: "/a.ts",
content: "export defai;t class A {}"
};
const b = {
path: "/b.ts",
content: "import type A from './a'; export default A;"
};
const c = {
path: "/c.ts",
content: "import A from './b'; new A();"
};
assertUsageError([a, b, c], c);
});
});
function assertUsageError(files: readonly TestFSWithWatch.File[], openFile: TestFSWithWatch.File) {
const host = createServerHost(files);
const session = createSession(host);
openFilesForSession([openFile], session);
const req = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
protocol.CommandTypes.SemanticDiagnosticsSync,
{ file: openFile.path }
);
const diagnostics = session.executeCommand(req).response as protocol.Diagnostic[];
assert.lengthOf(diagnostics, 1);
assert.oneOf(diagnostics[0].code, [
Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type.code,
Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type.code
]);
}
}

View File

@ -0,0 +1,43 @@
/d.ts(2,5): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
/e.ts(2,11): error TS2339: Property 'A' does not exist on type 'typeof import("/b")'.
/f.ts(2,11): error TS2339: Property 'default' does not exist on type 'typeof import("/b")'.
/g.ts(2,5): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
==== /a.ts (0 errors) ====
export class A {}
==== /b.ts (0 errors) ====
import type * as types from './a';
export default types;
==== /c.ts (0 errors) ====
import * as types from './a';
export default types;
==== /d.ts (1 errors) ====
import types from './b';
new types.A(); // Error
~~~~~
!!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
!!! related TS1376 /b.ts:1:13: 'types' was imported here.
==== /e.ts (1 errors) ====
import types = require('./b');
new types.A(); // Error
~
!!! error TS2339: Property 'A' does not exist on type 'typeof import("/b")'.
==== /f.ts (1 errors) ====
import * as types from './b';
new types.default.A(); // Error
~~~~~~~
!!! error TS2339: Property 'default' does not exist on type 'typeof import("/b")'.
==== /g.ts (1 errors) ====
import type types from './c'
new types.A(); // Error
~~~~~
!!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
!!! related TS1376 /g.ts:1:8: 'types' was imported here.

View File

@ -0,0 +1,80 @@
//// [tests/cases/conformance/externalModules/typeOnly/exportDefault.ts] ////
//// [a.ts]
export class A {}
//// [b.ts]
import type * as types from './a';
export default types;
//// [c.ts]
import * as types from './a';
export default types;
//// [d.ts]
import types from './b';
new types.A(); // Error
//// [e.ts]
import types = require('./b');
new types.A(); // Error
//// [f.ts]
import * as types from './b';
new types.default.A(); // Error
//// [g.ts]
import type types from './c'
new types.A(); // Error
//// [a.js]
"use strict";
exports.__esModule = true;
var A = /** @class */ (function () {
function A() {
}
return A;
}());
exports.A = A;
//// [b.js]
"use strict";
exports.__esModule = true;
exports["default"] = types;
//// [c.js]
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
exports.__esModule = true;
var types = __importStar(require("./a"));
exports["default"] = types;
//// [d.js]
"use strict";
exports.__esModule = true;
new types.A(); // Error
//// [e.js]
"use strict";
exports.__esModule = true;
var types = require("./b");
new types.A(); // Error
//// [f.js]
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
exports.__esModule = true;
var types = __importStar(require("./b"));
new types["default"].A(); // Error
//// [g.js]
"use strict";
exports.__esModule = true;
new types.A(); // Error

View File

@ -0,0 +1,50 @@
=== /a.ts ===
export class A {}
>A : Symbol(A, Decl(a.ts, 0, 0))
=== /b.ts ===
import type * as types from './a';
>types : Symbol(types, Decl(b.ts, 0, 11))
export default types;
>types : Symbol(types, Decl(b.ts, 0, 11))
=== /c.ts ===
import * as types from './a';
>types : Symbol(types, Decl(c.ts, 0, 6))
export default types;
>types : Symbol(types, Decl(c.ts, 0, 6))
=== /d.ts ===
import types from './b';
>types : Symbol(types, Decl(d.ts, 0, 6))
new types.A(); // Error
>types.A : Symbol(types.A, Decl(a.ts, 0, 0))
>types : Symbol(types, Decl(d.ts, 0, 6))
>A : Symbol(types.A, Decl(a.ts, 0, 0))
=== /e.ts ===
import types = require('./b');
>types : Symbol(types, Decl(e.ts, 0, 0))
new types.A(); // Error
>types : Symbol(types, Decl(e.ts, 0, 0))
=== /f.ts ===
import * as types from './b';
>types : Symbol(types, Decl(f.ts, 0, 6))
new types.default.A(); // Error
>types : Symbol(types, Decl(f.ts, 0, 6))
=== /g.ts ===
import type types from './c'
>types : Symbol(types, Decl(g.ts, 0, 6))
new types.A(); // Error
>types.A : Symbol(types.A, Decl(a.ts, 0, 0))
>types : Symbol(types, Decl(g.ts, 0, 6))
>A : Symbol(types.A, Decl(a.ts, 0, 0))

View File

@ -0,0 +1,60 @@
=== /a.ts ===
export class A {}
>A : A
=== /b.ts ===
import type * as types from './a';
>types : typeof types
export default types;
>types : typeof types
=== /c.ts ===
import * as types from './a';
>types : typeof types
export default types;
>types : typeof types
=== /d.ts ===
import types from './b';
>types : typeof types
new types.A(); // Error
>new types.A() : types.A
>types.A : typeof types.A
>types : typeof types
>A : typeof types.A
=== /e.ts ===
import types = require('./b');
>types : typeof types
new types.A(); // Error
>new types.A() : any
>types.A : any
>types : typeof types
>A : any
=== /f.ts ===
import * as types from './b';
>types : typeof types
new types.default.A(); // Error
>new types.default.A() : any
>types.default.A : any
>types.default : any
>types : typeof types
>default : any
>A : any
=== /g.ts ===
import type types from './c'
>types : any
new types.A(); // Error
>new types.A() : types.A
>types.A : typeof types.A
>types : typeof types
>A : typeof types.A

View File

@ -0,0 +1,30 @@
tests/cases/conformance/externalModules/typeOnly/index.ts(9,17): error TS1361: 'C' cannot be used as a value because it was imported using 'import type'.
tests/cases/conformance/externalModules/typeOnly/index.ts(10,17): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
==== tests/cases/conformance/externalModules/typeOnly/types.ts (0 errors) ====
export interface I {}
export class C {}
==== tests/cases/conformance/externalModules/typeOnly/ns.ts (0 errors) ====
import type * as types from './types';
export { types };
==== tests/cases/conformance/externalModules/typeOnly/index.ts (2 errors) ====
import { types } from './ns';
import type { C, I } from './types';
interface Q extends C {}
interface R extends I {}
interface S extends types.C {}
interface T extends types.I {}
class U extends C {} // Error
~
!!! error TS1361: 'C' cannot be used as a value because it was imported using 'import type'.
!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/index.ts:2:15: 'C' was imported here.
class V extends types.C {} // Error
~~~~~
!!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/ns.ts:1:13: 'types' was imported here.

View File

@ -0,0 +1,65 @@
//// [tests/cases/conformance/externalModules/typeOnly/extendsClause.ts] ////
//// [types.ts]
export interface I {}
export class C {}
//// [ns.ts]
import type * as types from './types';
export { types };
//// [index.ts]
import { types } from './ns';
import type { C, I } from './types';
interface Q extends C {}
interface R extends I {}
interface S extends types.C {}
interface T extends types.I {}
class U extends C {} // Error
class V extends types.C {} // Error
//// [types.js]
"use strict";
exports.__esModule = true;
var C = /** @class */ (function () {
function C() {
}
return C;
}());
exports.C = C;
//// [ns.js]
"use strict";
exports.__esModule = true;
//// [index.js]
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var U = /** @class */ (function (_super) {
__extends(U, _super);
function U() {
return _super !== null && _super.apply(this, arguments) || this;
}
return U;
}(C)); // Error
var V = /** @class */ (function (_super) {
__extends(V, _super);
function V() {
return _super !== null && _super.apply(this, arguments) || this;
}
return V;
}(types.C)); // Error

View File

@ -0,0 +1,52 @@
=== tests/cases/conformance/externalModules/typeOnly/types.ts ===
export interface I {}
>I : Symbol(I, Decl(types.ts, 0, 0))
export class C {}
>C : Symbol(C, Decl(types.ts, 0, 21))
=== tests/cases/conformance/externalModules/typeOnly/ns.ts ===
import type * as types from './types';
>types : Symbol(types, Decl(ns.ts, 0, 11))
export { types };
>types : Symbol(types, Decl(ns.ts, 1, 8))
=== tests/cases/conformance/externalModules/typeOnly/index.ts ===
import { types } from './ns';
>types : Symbol(types, Decl(index.ts, 0, 8))
import type { C, I } from './types';
>C : Symbol(C, Decl(index.ts, 1, 13))
>I : Symbol(I, Decl(index.ts, 1, 16))
interface Q extends C {}
>Q : Symbol(Q, Decl(index.ts, 1, 36))
>C : Symbol(C, Decl(index.ts, 1, 13))
interface R extends I {}
>R : Symbol(R, Decl(index.ts, 3, 24))
>I : Symbol(I, Decl(index.ts, 1, 16))
interface S extends types.C {}
>S : Symbol(S, Decl(index.ts, 4, 24))
>types.C : Symbol(types.C, Decl(types.ts, 0, 21))
>types : Symbol(types, Decl(index.ts, 0, 8))
>C : Symbol(types.C, Decl(types.ts, 0, 21))
interface T extends types.I {}
>T : Symbol(T, Decl(index.ts, 5, 30))
>types.I : Symbol(types.I, Decl(types.ts, 0, 0))
>types : Symbol(types, Decl(index.ts, 0, 8))
>I : Symbol(types.I, Decl(types.ts, 0, 0))
class U extends C {} // Error
>U : Symbol(U, Decl(index.ts, 6, 30))
>C : Symbol(C, Decl(index.ts, 1, 13))
class V extends types.C {} // Error
>V : Symbol(V, Decl(index.ts, 8, 20))
>types.C : Symbol(types.C, Decl(types.ts, 0, 21))
>types : Symbol(types, Decl(index.ts, 0, 8))
>C : Symbol(types.C, Decl(types.ts, 0, 21))

View File

@ -0,0 +1,38 @@
=== tests/cases/conformance/externalModules/typeOnly/types.ts ===
export interface I {}
export class C {}
>C : C
=== tests/cases/conformance/externalModules/typeOnly/ns.ts ===
import type * as types from './types';
>types : typeof types
export { types };
>types : typeof types
=== tests/cases/conformance/externalModules/typeOnly/index.ts ===
import { types } from './ns';
>types : typeof types
import type { C, I } from './types';
>C : types.C
>I : types.I
interface Q extends C {}
interface R extends I {}
interface S extends types.C {}
>types : typeof types
interface T extends types.I {}
>types : typeof types
class U extends C {} // Error
>U : U
>C : types.C
class V extends types.C {} // Error
>V : V
>types.C : types.C
>types : typeof types
>C : typeof types.C

View File

@ -0,0 +1,45 @@
/d.ts(2,5): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
/e.ts(2,5): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
/f.ts(2,5): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
/g.ts(2,5): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
==== /a.ts (0 errors) ====
export class A {}
==== /b.ts (0 errors) ====
import type * as types from './a';
export = types; // Error
==== /c.ts (0 errors) ====
import * as types from './a';
export = types;
==== /d.ts (1 errors) ====
import types from './b';
new types.A(); // Error
~~~~~
!!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
!!! related TS1376 /b.ts:1:13: 'types' was imported here.
==== /e.ts (1 errors) ====
import types = require('./b');
new types.A(); // Error
~~~~~
!!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
!!! related TS1376 /b.ts:1:13: 'types' was imported here.
==== /f.ts (1 errors) ====
import * as types from './b';
new types.A(); // Error
~~~~~
!!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
!!! related TS1376 /b.ts:1:13: 'types' was imported here.
==== /g.ts (1 errors) ====
import type types from './c'
new types.A(); // Error
~~~~~
!!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'.
!!! related TS1376 /g.ts:1:8: 'types' was imported here.

View File

@ -0,0 +1,69 @@
//// [tests/cases/conformance/externalModules/typeOnly/importEquals1.ts] ////
//// [a.ts]
export class A {}
//// [b.ts]
import type * as types from './a';
export = types; // Error
//// [c.ts]
import * as types from './a';
export = types;
//// [d.ts]
import types from './b';
new types.A(); // Error
//// [e.ts]
import types = require('./b');
new types.A(); // Error
//// [f.ts]
import * as types from './b';
new types.A(); // Error
//// [g.ts]
import type types from './c'
new types.A(); // Error
//// [a.js]
"use strict";
exports.__esModule = true;
var A = /** @class */ (function () {
function A() {
}
return A;
}());
exports.A = A;
//// [b.js]
"use strict";
module.exports = types;
//// [c.js]
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var types = __importStar(require("./a"));
module.exports = types;
//// [d.js]
"use strict";
exports.__esModule = true;
new types.A(); // Error
//// [e.js]
"use strict";
exports.__esModule = true;
new types.A(); // Error
//// [f.js]
"use strict";
exports.__esModule = true;
new types.A(); // Error
//// [g.js]
"use strict";
exports.__esModule = true;
new types.A(); // Error

View File

@ -0,0 +1,54 @@
=== /a.ts ===
export class A {}
>A : Symbol(A, Decl(a.ts, 0, 0))
=== /b.ts ===
import type * as types from './a';
>types : Symbol(types, Decl(b.ts, 0, 11))
export = types; // Error
>types : Symbol(types, Decl(b.ts, 0, 11))
=== /c.ts ===
import * as types from './a';
>types : Symbol(types, Decl(c.ts, 0, 6))
export = types;
>types : Symbol(types, Decl(c.ts, 0, 6))
=== /d.ts ===
import types from './b';
>types : Symbol(types, Decl(d.ts, 0, 6))
new types.A(); // Error
>types.A : Symbol(types.A, Decl(a.ts, 0, 0))
>types : Symbol(types, Decl(d.ts, 0, 6))
>A : Symbol(types.A, Decl(a.ts, 0, 0))
=== /e.ts ===
import types = require('./b');
>types : Symbol(types, Decl(e.ts, 0, 0))
new types.A(); // Error
>types.A : Symbol(types.A, Decl(a.ts, 0, 0))
>types : Symbol(types, Decl(e.ts, 0, 0))
>A : Symbol(types.A, Decl(a.ts, 0, 0))
=== /f.ts ===
import * as types from './b';
>types : Symbol(types, Decl(f.ts, 0, 6))
new types.A(); // Error
>types.A : Symbol(types.A, Decl(a.ts, 0, 0))
>types : Symbol(types, Decl(f.ts, 0, 6))
>A : Symbol(types.A, Decl(a.ts, 0, 0))
=== /g.ts ===
import type types from './c'
>types : Symbol(types, Decl(g.ts, 0, 6))
new types.A(); // Error
>types.A : Symbol(types.A, Decl(a.ts, 0, 0))
>types : Symbol(types, Decl(g.ts, 0, 6))
>A : Symbol(types.A, Decl(a.ts, 0, 0))

View File

@ -0,0 +1,58 @@
=== /a.ts ===
export class A {}
>A : A
=== /b.ts ===
import type * as types from './a';
>types : typeof types
export = types; // Error
>types : typeof types
=== /c.ts ===
import * as types from './a';
>types : typeof types
export = types;
>types : typeof types
=== /d.ts ===
import types from './b';
>types : typeof types
new types.A(); // Error
>new types.A() : types.A
>types.A : typeof types.A
>types : typeof types
>A : typeof types.A
=== /e.ts ===
import types = require('./b');
>types : typeof types
new types.A(); // Error
>new types.A() : types.A
>types.A : typeof types.A
>types : typeof types
>A : typeof types.A
=== /f.ts ===
import * as types from './b';
>types : typeof types
new types.A(); // Error
>new types.A() : types.A
>types.A : typeof types.A
>types : typeof types
>A : typeof types.A
=== /g.ts ===
import type types from './c'
>types : any
new types.A(); // Error
>new types.A() : types.A
>types.A : typeof types.A
>types : typeof types
>A : typeof types.A

View File

@ -0,0 +1,17 @@
/c.ts(2,7): error TS2339: Property 'A' does not exist on type 'typeof import("/a")'.
==== /c.ts (1 errors) ====
import a = require('./b');
new a.A(); // Error
~
!!! error TS2339: Property 'A' does not exist on type 'typeof import("/a")'.
==== /a.ts (0 errors) ====
class A {}
export type { A }
==== /b.ts (0 errors) ====
import * as a from './a';
export = a;

View File

@ -0,0 +1,39 @@
//// [tests/cases/conformance/externalModules/typeOnly/importEquals2.ts] ////
//// [a.ts]
class A {}
export type { A }
//// [b.ts]
import * as a from './a';
export = a;
//// [c.ts]
import a = require('./b');
new a.A(); // Error
//// [a.js]
"use strict";
exports.__esModule = true;
var A = /** @class */ (function () {
function A() {
}
return A;
}());
//// [b.js]
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var a = __importStar(require("./a"));
module.exports = a;
//// [c.js]
"use strict";
exports.__esModule = true;
var a = require("./b");
new a.A(); // Error

View File

@ -0,0 +1,21 @@
=== /c.ts ===
import a = require('./b');
>a : Symbol(a, Decl(c.ts, 0, 0))
new a.A(); // Error
>a : Symbol(a, Decl(c.ts, 0, 0))
=== /a.ts ===
class A {}
>A : Symbol(A, Decl(a.ts, 0, 0))
export type { A }
>A : Symbol(A, Decl(a.ts, 1, 13))
=== /b.ts ===
import * as a from './a';
>a : Symbol(a, Decl(b.ts, 0, 6))
export = a;
>a : Symbol(a, Decl(b.ts, 0, 6))

View File

@ -0,0 +1,24 @@
=== /c.ts ===
import a = require('./b');
>a : typeof a
new a.A(); // Error
>new a.A() : any
>a.A : any
>a : typeof a
>A : any
=== /a.ts ===
class A {}
>A : A
export type { A }
>A : A
=== /b.ts ===
import * as a from './a';
>a : typeof a
export = a;
>a : typeof a

View File

@ -0,0 +1,37 @@
tests/cases/conformance/externalModules/typeOnly/b.ts(2,12): error TS1380: An import alias cannot reference a declaration that was imported using 'import type'.
tests/cases/conformance/externalModules/typeOnly/b.ts(3,13): error TS1380: An import alias cannot reference a declaration that was imported using 'import type'.
tests/cases/conformance/externalModules/typeOnly/c.ts(2,12): error TS1380: An import alias cannot reference a declaration that was imported using 'import type'.
tests/cases/conformance/externalModules/typeOnly/c.ts(3,13): error TS1380: An import alias cannot reference a declaration that was imported using 'import type'.
==== tests/cases/conformance/externalModules/typeOnly/a.ts (0 errors) ====
export class A {}
==== tests/cases/conformance/externalModules/typeOnly/b.ts (2 errors) ====
import type * as a from './a';
import A = a.A; // Error
~~~
!!! error TS1380: An import alias cannot reference a declaration that was imported using 'import type'.
!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/b.ts:1:13: 'a' was imported here.
import aa = a; // Error
~
!!! error TS1380: An import alias cannot reference a declaration that was imported using 'import type'.
!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/b.ts:1:13: 'a' was imported here.
const x = 0;
export { a, A, x };
==== tests/cases/conformance/externalModules/typeOnly/c.ts (2 errors) ====
import * as b from './b';
import A = b.a.A; // Error
~~~~~
!!! error TS1380: An import alias cannot reference a declaration that was imported using 'import type'.
!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/b.ts:1:13: 'a' was imported here.
import AA = b.A; // Error
~~~
!!! error TS1380: An import alias cannot reference a declaration that was imported using 'import type'.
!!! related TS1376 tests/cases/conformance/externalModules/typeOnly/b.ts:1:13: 'a' was imported here.
import x = b.x;
console.log(x);

View File

@ -0,0 +1,42 @@
//// [tests/cases/conformance/externalModules/typeOnly/importEquals3.ts] ////
//// [a.ts]
export class A {}
//// [b.ts]
import type * as a from './a';
import A = a.A; // Error
import aa = a; // Error
const x = 0;
export { a, A, x };
//// [c.ts]
import * as b from './b';
import A = b.a.A; // Error
import AA = b.A; // Error
import x = b.x;
console.log(x);
//// [a.js]
"use strict";
exports.__esModule = true;
var A = /** @class */ (function () {
function A() {
}
return A;
}());
exports.A = A;
//// [b.js]
"use strict";
exports.__esModule = true;
var x = 0;
exports.x = x;
//// [c.js]
"use strict";
exports.__esModule = true;
var b = require("./b");
var x = b.x;
console.log(x);

View File

@ -0,0 +1,51 @@
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
export class A {}
>A : Symbol(A, Decl(a.ts, 0, 0))
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
import type * as a from './a';
>a : Symbol(a, Decl(b.ts, 0, 11))
import A = a.A; // Error
>A : Symbol(A, Decl(b.ts, 0, 30))
>a : Symbol(a, Decl(b.ts, 0, 11))
>A : Symbol(a.A, Decl(a.ts, 0, 0))
import aa = a; // Error
>aa : Symbol(aa, Decl(b.ts, 1, 15))
>a : Symbol(a, Decl(b.ts, 0, 11))
const x = 0;
>x : Symbol(x, Decl(b.ts, 4, 5))
export { a, A, x };
>a : Symbol(a, Decl(b.ts, 5, 8))
>A : Symbol(A, Decl(b.ts, 5, 11))
>x : Symbol(x, Decl(b.ts, 5, 14))
=== tests/cases/conformance/externalModules/typeOnly/c.ts ===
import * as b from './b';
>b : Symbol(b, Decl(c.ts, 0, 6))
import A = b.a.A; // Error
>A : Symbol(A, Decl(c.ts, 0, 25))
>b : Symbol(b, Decl(c.ts, 0, 6))
>a : Symbol(b.a, Decl(b.ts, 5, 8))
>A : Symbol(b.a.A, Decl(a.ts, 0, 0))
import AA = b.A; // Error
>AA : Symbol(AA, Decl(c.ts, 1, 17))
>b : Symbol(b, Decl(c.ts, 0, 6))
>A : Symbol(b.A, Decl(b.ts, 5, 11))
import x = b.x;
>x : Symbol(x, Decl(c.ts, 2, 16))
>b : Symbol(b, Decl(c.ts, 0, 6))
>x : Symbol(b.x, Decl(b.ts, 5, 14))
console.log(x);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>x : Symbol(x, Decl(c.ts, 2, 16))

View File

@ -0,0 +1,53 @@
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
export class A {}
>A : A
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
import type * as a from './a';
>a : typeof a
import A = a.A; // Error
>A : typeof a.A
>a : typeof a
>A : a.A
import aa = a; // Error
>aa : typeof a
>a : typeof a
const x = 0;
>x : 0
>0 : 0
export { a, A, x };
>a : typeof a
>A : typeof a.A
>x : 0
=== tests/cases/conformance/externalModules/typeOnly/c.ts ===
import * as b from './b';
>b : typeof b
import A = b.a.A; // Error
>A : typeof b.a.A
>b : typeof b
>a : typeof b.a
>A : b.a.A
import AA = b.A; // Error
>AA : typeof b.a.A
>b : typeof b
>A : b.a.A
import x = b.x;
>x : 0
>b : typeof b
>x : 0
console.log(x);
>console.log(x) : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>x : 0

View File

@ -0,0 +1,28 @@
// @esModuleInterop: true
// @Filename: /a.ts
export class A {}
// @Filename: /b.ts
import type * as types from './a';
export default types;
// @Filename: /c.ts
import * as types from './a';
export default types;
// @Filename: /d.ts
import types from './b';
new types.A(); // Error
// @Filename: /e.ts
import types = require('./b');
new types.A(); // Error
// @Filename: /f.ts
import * as types from './b';
new types.default.A(); // Error
// @Filename: /g.ts
import type types from './c'
new types.A(); // Error

View File

@ -0,0 +1,19 @@
// @Filename: types.ts
export interface I {}
export class C {}
// @Filename: ns.ts
import type * as types from './types';
export { types };
// @Filename: index.ts
import { types } from './ns';
import type { C, I } from './types';
interface Q extends C {}
interface R extends I {}
interface S extends types.C {}
interface T extends types.I {}
class U extends C {} // Error
class V extends types.C {} // Error

View File

@ -0,0 +1,28 @@
// @esModuleInterop: true
// @Filename: /a.ts
export class A {}
// @Filename: /b.ts
import type * as types from './a';
export = types; // Error
// @Filename: /c.ts
import * as types from './a';
export = types;
// @Filename: /d.ts
import types from './b';
new types.A(); // Error
// @Filename: /e.ts
import types = require('./b');
new types.A(); // Error
// @Filename: /f.ts
import * as types from './b';
new types.A(); // Error
// @Filename: /g.ts
import type types from './c'
new types.A(); // Error

View File

@ -0,0 +1,13 @@
// @esModuleInterop: true
// @Filename: /a.ts
class A {}
export type { A }
// @Filename: /b.ts
import * as a from './a';
export = a;
// @Filename: /c.ts
import a = require('./b');
new a.A(); // Error

View File

@ -0,0 +1,18 @@
// @Filename: a.ts
export class A {}
// @Filename: b.ts
import type * as a from './a';
import A = a.A; // Error
import aa = a; // Error
const x = 0;
export { a, A, x };
// @Filename: c.ts
import * as b from './b';
import A = b.a.A; // Error
import AA = b.A; // Error
import x = b.x;
console.log(x);