mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix import= something type only from a module
This commit is contained in:
12 files changed
+397
-12
No files matched your search
+26
-10
@@ -2182,7 +2182,12 @@ 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);
|
||||
if (!markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, immediate)) {
|
||||
markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, resolved);
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias);
|
||||
}
|
||||
@@ -2278,7 +2283,9 @@ namespace ts {
|
||||
else if (hasSyntheticDefault) {
|
||||
// per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present
|
||||
const resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
|
||||
if (!isTypeOnly) markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, resolved);
|
||||
if (!isTypeOnly && !markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, moduleSymbol)) {
|
||||
markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, resolved);
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
if (!isTypeOnly) markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, exportDefaultSymbol);
|
||||
@@ -2289,8 +2296,11 @@ namespace ts {
|
||||
function getTargetOfNamespaceImport(node: NamespaceImport, dontResolveAlias: boolean): Symbol | undefined {
|
||||
const moduleSpecifier = node.parent.parent.moduleSpecifier;
|
||||
const isTypeOnly = markSymbolOfAliasDeclarationIfTypeOnly(node);
|
||||
const resolved = resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
|
||||
if (!isTypeOnly) markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, resolved);
|
||||
const immediate = resolveExternalModuleName(node, moduleSpecifier);
|
||||
const resolved = resolveESModuleSymbol(immediate, moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
|
||||
if (!isTypeOnly && !markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, immediate)) {
|
||||
markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, resolved);
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
@@ -2459,7 +2469,9 @@ namespace ts {
|
||||
|
||||
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);
|
||||
markSymbolOfAliasDeclarationIfResolvesToTypeOnly(node, resolved);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
function getTargetOfAliasLikeExpression(expression: Expression, dontResolveAlias: boolean) {
|
||||
@@ -2556,14 +2568,18 @@ namespace ts {
|
||||
return links.target;
|
||||
}
|
||||
|
||||
function markSymbolOfAliasDeclarationIfResolvesToTypeOnly(aliasDeclaration: TypeOnlyCompatibleAliasDeclaration | undefined, resolvesToSymbol: Symbol | undefined) {
|
||||
if (!aliasDeclaration || !resolvesToSymbol) return;
|
||||
function markSymbolOfAliasDeclarationIfResolvesToTypeOnly(aliasDeclaration: Declaration | undefined, resolvesToSymbol: Symbol | undefined): boolean {
|
||||
if (!aliasDeclaration || !resolvesToSymbol) return false;
|
||||
const sourceSymbol = getSymbolOfNode(aliasDeclaration);
|
||||
const links = getSymbolLinks(sourceSymbol);
|
||||
if (links.typeOnlyDeclaration === undefined) {
|
||||
resolvesToSymbol = resolvesToSymbol.exports?.get(InternalSymbolName.ExportEquals) ?? resolvesToSymbol;
|
||||
const typeOnly = find(resolvesToSymbol.declarations, isTypeOnlyImportOrExportDeclaration);
|
||||
links.typeOnlyDeclaration = typeOnly ?? getSymbolLinks(resolvesToSymbol).typeOnlyDeclaration ?? false;
|
||||
const decl = typeOnly ?? getSymbolLinks(resolvesToSymbol).typeOnlyDeclaration ?? false;
|
||||
links.typeOnlyDeclaration = decl;
|
||||
return !!decl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function markSymbolOfAliasDeclarationIfTypeOnly(aliasDeclaration: TypeOnlyCompatibleAliasDeclaration): boolean {
|
||||
@@ -2711,8 +2727,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 (isIdentifier(name) && (symbol.flags & SymbolFlags.Alias || name.parent.kind === SyntaxKind.ExportAssignment)) {
|
||||
markSymbolOfAliasDeclarationIfResolvesToTypeOnly(getAliasDeclarationFromName(name), symbol);
|
||||
}
|
||||
return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
|
||||
}
|
||||
|
||||
@@ -2766,13 +2766,14 @@ namespace ts {
|
||||
node.kind === SyntaxKind.PropertyAssignment && isAliasableExpression((node as PropertyAssignment).initializer);
|
||||
}
|
||||
|
||||
export function getTypeOnlyCompatibleAliasDeclarationFromName(node: Identifier): TypeOnlyCompatibleAliasDeclaration | undefined {
|
||||
export function getAliasDeclarationFromName(node: Identifier): 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:
|
||||
return node.parent as Declaration;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in new issue
Block a user