@@ -3443,7 +3443,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3443
3443
if (result && errorLocation && meaning & SymbolFlags.Value && result.flags & SymbolFlags.Alias && !(result.flags & SymbolFlags.Value) && !isValidTypeOnlyAliasUseSite(errorLocation)) {
3444
3444
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(result, SymbolFlags.Value);
3445
3445
if (typeOnlyDeclaration) {
3446
- const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
3446
+ const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier || typeOnlyDeclaration.kind === SyntaxKind.ExportDeclaration || typeOnlyDeclaration.kind === SyntaxKind.NamespaceExport
3447
3447
? Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type
3448
3448
: Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type;
3449
3449
const unescapedName = unescapeLeadingUnderscores(name);
@@ -3464,7 +3464,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3464
3464
diagnostic,
3465
3465
createDiagnosticForNode(
3466
3466
typeOnlyDeclaration,
3467
- typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier ? Diagnostics._0_was_exported_here : Diagnostics._0_was_imported_here,
3467
+ typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier || typeOnlyDeclaration.kind === SyntaxKind.ExportDeclaration || typeOnlyDeclaration.kind === SyntaxKind.NamespaceExport
3468
+ ? Diagnostics._0_was_exported_here
3469
+ : Diagnostics._0_was_imported_here,
3468
3470
unescapedName));
3469
3471
}
3470
3472
@@ -3861,15 +3863,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3861
3863
function checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node: ImportEqualsDeclaration, resolved: Symbol | undefined) {
3862
3864
if (markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false) && !node.isTypeOnly) {
3863
3865
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(getSymbolOfDeclaration(node))!;
3864
- const isExport = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier;
3866
+ const isExport = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier || typeOnlyDeclaration.kind === SyntaxKind.ExportDeclaration ;
3865
3867
const message = isExport
3866
3868
? Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type
3867
3869
: Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type;
3868
3870
const relatedMessage = isExport
3869
3871
? Diagnostics._0_was_exported_here
3870
3872
: Diagnostics._0_was_imported_here;
3871
3873
3872
- const name = unescapeLeadingUnderscores(typeOnlyDeclaration.name.escapedText);
3874
+ // TODO: how to get name for export *?
3875
+ const name = typeOnlyDeclaration.kind === SyntaxKind.ExportDeclaration ? "*" : unescapeLeadingUnderscores(typeOnlyDeclaration.name.escapedText);
3873
3876
addRelatedInfo(error(node.moduleReference, message), createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, name));
3874
3877
}
3875
3878
}
@@ -4083,7 +4086,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4083
4086
if (symbol.flags & SymbolFlags.Module) {
4084
4087
const exportSymbol = getExportsOfSymbol(symbol).get(name.escapedText);
4085
4088
const resolved = resolveSymbol(exportSymbol, dontResolveAlias);
4086
- markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false);
4089
+ const exportStarDeclaration = getSymbolLinks(symbol).typeOnlyExportStarMap?.get(name.escapedText);
4090
+ markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false, exportStarDeclaration, name.escapedText);
4087
4091
return resolved;
4088
4092
}
4089
4093
}
@@ -4444,6 +4448,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4444
4448
immediateTarget: Symbol | undefined,
4445
4449
finalTarget: Symbol | undefined,
4446
4450
overwriteEmpty: boolean,
4451
+ exportStarDeclaration?: ExportDeclaration & { readonly isTypeOnly: true },
4452
+ exportStarName?: __String,
4447
4453
): boolean {
4448
4454
if (!aliasDeclaration || isPropertyAccessExpression(aliasDeclaration)) return false;
4449
4455
@@ -4455,6 +4461,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4455
4461
links.typeOnlyDeclaration = aliasDeclaration;
4456
4462
return true;
4457
4463
}
4464
+ if (exportStarDeclaration) {
4465
+ const links = getSymbolLinks(sourceSymbol);
4466
+ links.typeOnlyDeclaration = exportStarDeclaration;
4467
+ if (sourceSymbol.escapedName !== exportStarName) {
4468
+ links.typeOnlyExportStarName = exportStarName;
4469
+ }
4470
+ return true;
4471
+ }
4458
4472
4459
4473
const links = getSymbolLinks(sourceSymbol);
4460
4474
return markSymbolOfAliasDeclarationIfTypeOnlyWorker(links, immediateTarget, overwriteEmpty)
@@ -4480,7 +4494,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4480
4494
return links.typeOnlyDeclaration || undefined;
4481
4495
}
4482
4496
if (links.typeOnlyDeclaration) {
4483
- return getAllSymbolFlags(resolveAlias(links.typeOnlyDeclaration.symbol)) & include ? links.typeOnlyDeclaration : undefined;
4497
+ const resolved = links.typeOnlyDeclaration.kind === SyntaxKind.ExportDeclaration
4498
+ ? resolveSymbol(getExportsOfModule(links.typeOnlyDeclaration.symbol.parent!).get(links.typeOnlyExportStarName || symbol.escapedName))!
4499
+ : resolveAlias(links.typeOnlyDeclaration.symbol);
4500
+ return getAllSymbolFlags(resolved) & include ? links.typeOnlyDeclaration : undefined;
4484
4501
}
4485
4502
return undefined;
4486
4503
}
@@ -5203,7 +5220,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5203
5220
5204
5221
function getExportsOfModule(moduleSymbol: Symbol): SymbolTable {
5205
5222
const links = getSymbolLinks(moduleSymbol);
5206
- return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol));
5223
+ if (!links.resolvedExports) {
5224
+ const { exports, typeOnlyExportStarMap } = getExportsOfModuleWorker(moduleSymbol);
5225
+ links.resolvedExports = exports;
5226
+ links.typeOnlyExportStarMap = typeOnlyExportStarMap;
5227
+ }
5228
+ return links.resolvedExports;
5207
5229
}
5208
5230
5209
5231
interface ExportCollisionTracker {
@@ -5243,21 +5265,38 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5243
5265
});
5244
5266
}
5245
5267
5246
- function getExportsOfModuleWorker(moduleSymbol: Symbol): SymbolTable {
5268
+ function getExportsOfModuleWorker(moduleSymbol: Symbol) {
5247
5269
const visitedSymbols: Symbol[] = [];
5270
+ let typeOnlyExportStarMap: UnderscoreEscapedMap<ExportDeclaration & { readonly isTypeOnly: true }> | undefined;
5271
+ const nonTypeOnlyNames = new Set<__String>();
5248
5272
5249
5273
// A module defined by an 'export=' consists of one export that needs to be resolved
5250
5274
moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
5275
+ const exports = visit(moduleSymbol) || emptySymbols;
5251
5276
5252
- return visit(moduleSymbol) || emptySymbols;
5277
+ if (typeOnlyExportStarMap) {
5278
+ nonTypeOnlyNames.forEach(name => typeOnlyExportStarMap!.delete(name));
5279
+ }
5280
+
5281
+ return {
5282
+ exports,
5283
+ typeOnlyExportStarMap,
5284
+ };
5253
5285
5254
5286
// The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
5255
5287
// module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error.
5256
- function visit(symbol: Symbol | undefined): SymbolTable | undefined {
5288
+ function visit(symbol: Symbol | undefined, exportStar?: ExportDeclaration, isTypeOnly?: boolean): SymbolTable | undefined {
5289
+ if (!isTypeOnly && symbol?.exports) {
5290
+ // Add non-type-only names before checking if we've visited this module,
5291
+ // because we might have visited it via an 'export type *', and visiting
5292
+ // again with 'export *' will override the type-onlyness of its exports.
5293
+ symbol.exports.forEach((_, name) => nonTypeOnlyNames.add(name));
5294
+ }
5257
5295
if (!(symbol && symbol.exports && pushIfUnique(visitedSymbols, symbol))) {
5258
5296
return;
5259
5297
}
5260
5298
const symbols = new Map(symbol.exports);
5299
+
5261
5300
// All export * declarations are collected in an __export symbol by the binder
5262
5301
const exportStars = symbol.exports.get(InternalSymbolName.ExportStar);
5263
5302
if (exportStars) {
@@ -5266,7 +5305,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5266
5305
if (exportStars.declarations) {
5267
5306
for (const node of exportStars.declarations) {
5268
5307
const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier!);
5269
- const exportedSymbols = visit(resolvedModule);
5308
+ const exportedSymbols = visit(resolvedModule, node as ExportDeclaration, isTypeOnly || (node as ExportDeclaration).isTypeOnly );
5270
5309
extendExportSymbols(
5271
5310
nestedSymbols,
5272
5311
exportedSymbols,
@@ -5291,6 +5330,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5291
5330
});
5292
5331
extendExportSymbols(symbols, nestedSymbols);
5293
5332
}
5333
+ if (exportStar?.isTypeOnly) {
5334
+ typeOnlyExportStarMap ??= new Map();
5335
+ symbols.forEach((_, escapedName) => typeOnlyExportStarMap!.set(
5336
+ escapedName,
5337
+ exportStar as ExportDeclaration & { readonly isTypeOnly: true }));
5338
+ }
5294
5339
return symbols;
5295
5340
}
5296
5341
}
@@ -8597,7 +8642,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
8597
8642
for (const node of symbol.declarations) {
8598
8643
const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier!);
8599
8644
if (!resolvedModule) continue;
8600
- addResult(factory.createExportDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false , /*exportClause*/ undefined, factory.createStringLiteral(getSpecifierForModuleSymbol(resolvedModule, context))), ModifierFlags.None);
8645
+ addResult(factory.createExportDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ (node as ExportDeclaration).isTypeOnly , /*exportClause*/ undefined, factory.createStringLiteral(getSpecifierForModuleSymbol(resolvedModule, context))), ModifierFlags.None);
8601
8646
}
8602
8647
}
8603
8648
}
@@ -12219,7 +12264,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
12219
12264
if (!links[resolutionKind]) {
12220
12265
const isStatic = resolutionKind === MembersOrExportsResolutionKind.resolvedExports;
12221
12266
const earlySymbols = !isStatic ? symbol.members :
12222
- symbol.flags & SymbolFlags.Module ? getExportsOfModuleWorker(symbol) :
12267
+ symbol.flags & SymbolFlags.Module ? getExportsOfModuleWorker(symbol).exports :
12223
12268
symbol.exports;
12224
12269
12225
12270
// In the event we recursively resolve the members/exports of the symbol, we
@@ -43738,13 +43783,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
43738
43783
}
43739
43784
43740
43785
function checkGrammarExportDeclaration(node: ExportDeclaration): boolean {
43741
- if (node.isTypeOnly) {
43742
- if (node.exportClause?.kind === SyntaxKind.NamedExports) {
43743
- return checkGrammarNamedImportsOrExports(node.exportClause);
43744
- }
43745
- else {
43746
- return grammarErrorOnNode(node, Diagnostics.Only_named_exports_may_use_export_type);
43747
- }
43786
+ if (node.isTypeOnly && node.exportClause?.kind === SyntaxKind.NamedExports) {
43787
+ return checkGrammarNamedImportsOrExports(node.exportClause);
43748
43788
}
43749
43789
return false;
43750
43790
}
0 commit comments