diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 670bd15ee46..923695ae158 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2710,7 +2710,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return symbol; } if (symbol.flags & SymbolFlags.Alias) { - const targetFlags = getAllSymbolFlags(symbol); + const targetFlags = getSymbolFlags(symbol); // `targetFlags` will be `SymbolFlags.All` if an error occurred in alias resolution; this avoids cascading errors if (targetFlags & meaning) { return symbol; @@ -3729,7 +3729,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return true; } const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); - const allFlags = symbol && getAllSymbolFlags(symbol); + const allFlags = symbol && getSymbolFlags(symbol); if (symbol && allFlags !== undefined && !(allFlags & SymbolFlags.Value)) { const rawName = unescapeLeadingUnderscores(name); if (isES2015OrLaterConstructorName(name)) { @@ -4462,32 +4462,44 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * @returns SymbolFlags.All if `symbol` is an alias that ultimately resolves to `unknown`; * combined flags of all alias targets otherwise. */ - function getAllSymbolFlags(symbol: Symbol): SymbolFlags { - let flags = symbol.flags; - let seenSymbols; - while (symbol.flags & SymbolFlags.Alias) { - const target = resolveAlias(symbol); - if (target === unknownSymbol) { - return SymbolFlags.All; - } + function getSymbolFlags(symbol: Symbol, excludeTypeOnlyMeanings?: boolean, excludeLocalMeanings?: boolean): SymbolFlags { + const typeOnlyDeclaration = excludeTypeOnlyMeanings && getTypeOnlyAliasDeclaration(symbol); + const typeOnlyDeclarationIsExportStar = typeOnlyDeclaration && isExportDeclaration(typeOnlyDeclaration); + const typeOnlyResolution = typeOnlyDeclaration && ( + typeOnlyDeclarationIsExportStar + ? resolveExternalModuleName(typeOnlyDeclaration.moduleSpecifier, typeOnlyDeclaration.moduleSpecifier, /*ignoreErrors*/ true) + : resolveAlias(typeOnlyDeclaration.symbol)); + const typeOnlyExportStarTargets = typeOnlyDeclarationIsExportStar && typeOnlyResolution ? getExportsOfModule(typeOnlyResolution) : undefined; + let flags = excludeLocalMeanings ? SymbolFlags.None : symbol.flags; + let seenSymbols; + while (symbol.flags & SymbolFlags.Alias) { + const target = getExportSymbolOfValueSymbolIfExported(resolveAlias(symbol)); + if (!typeOnlyDeclarationIsExportStar && target === typeOnlyResolution || + typeOnlyExportStarTargets?.get(target.escapedName) === target + ) { + break; + } + if (target === unknownSymbol) { + return SymbolFlags.All; + } - // Optimizations - try to avoid creating or adding to - // `seenSymbols` if possible - if (target === symbol || seenSymbols?.has(target)) { - break; - } - if (target.flags & SymbolFlags.Alias) { - if (seenSymbols) { - seenSymbols.add(target); - } - else { - seenSymbols = new Set([symbol, target]); - } - } - flags |= target.flags; - symbol = target; - } - return flags; + // Optimizations - try to avoid creating or adding to + // `seenSymbols` if possible + if (target === symbol || seenSymbols?.has(target)) { + break; + } + if (target.flags & SymbolFlags.Alias) { + if (seenSymbols) { + seenSymbols.add(target); + } + else { + seenSymbols = new Set([symbol, target]); + } + } + flags |= target.flags; + symbol = target; + } + return flags; } /** @@ -4515,7 +4527,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { immediateTarget: Symbol | undefined, finalTarget: Symbol | undefined, overwriteEmpty: boolean, - exportStarDeclaration?: ExportDeclaration & { readonly isTypeOnly: true }, + exportStarDeclaration?: ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression }, exportStarName?: __String, ): boolean { if (!aliasDeclaration || isPropertyAccessExpression(aliasDeclaration)) return false; @@ -4564,7 +4576,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const resolved = links.typeOnlyDeclaration.kind === SyntaxKind.ExportDeclaration ? resolveSymbol(getExportsOfModule(links.typeOnlyDeclaration.symbol.parent!).get(links.typeOnlyExportStarName || symbol.escapedName))! : resolveAlias(links.typeOnlyDeclaration.symbol); - return getAllSymbolFlags(resolved) & include ? links.typeOnlyDeclaration : undefined; + return getSymbolFlags(resolved) & include ? links.typeOnlyDeclaration : undefined; } return undefined; } @@ -4577,7 +4589,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const target = resolveAlias(symbol); if (target) { const markAlias = target === unknownSymbol || - ((getAllSymbolFlags(target) & SymbolFlags.Value) && !isConstEnumOrConstEnumOnlyModule(target) && !getTypeOnlyAliasDeclaration(symbol, SymbolFlags.Value)); + ((getSymbolFlags(symbol, /*excludeTypeOnlyMeanings*/ true) & SymbolFlags.Value) && !isConstEnumOrConstEnumOnlyModule(target)); if (markAlias) { markAliasSymbolAsReferenced(symbol); @@ -4599,7 +4611,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // This way a chain of imports can be elided if ultimately the final input is only used in a type // position. if (isInternalModuleImportEqualsDeclaration(node)) { - if (getAllSymbolFlags(resolveSymbol(symbol)) & SymbolFlags.Value) { + if (getSymbolFlags(resolveSymbol(symbol)) & SymbolFlags.Value) { // import foo = checkExpressionCached(node.moduleReference as Expression); } @@ -5319,7 +5331,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getExportsOfModuleWorker(moduleSymbol: Symbol) { const visitedSymbols: Symbol[] = []; - let typeOnlyExportStarMap: Map<__String, ExportDeclaration & { readonly isTypeOnly: true }> | undefined; + let typeOnlyExportStarMap: Map<__String, ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression }> | undefined; const nonTypeOnlyNames = new Set<__String>(); // A module defined by an 'export=' consists of one export that needs to be resolved @@ -5386,7 +5398,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { typeOnlyExportStarMap ??= new Map(); symbols.forEach((_, escapedName) => typeOnlyExportStarMap!.set( escapedName, - exportStar as ExportDeclaration & { readonly isTypeOnly: true })); + exportStar as ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression })); } return symbols; } @@ -5577,7 +5589,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function symbolIsValue(symbol: Symbol, includeTypeOnlyMembers?: boolean): boolean { return !!( symbol.flags & SymbolFlags.Value || - symbol.flags & SymbolFlags.Alias && getAllSymbolFlags(symbol) & SymbolFlags.Value && (includeTypeOnlyMembers || !getTypeOnlyAliasDeclaration(symbol))); + symbol.flags & SymbolFlags.Alias && getSymbolFlags(symbol, !includeTypeOnlyMembers) & SymbolFlags.Value); } function findConstructorDeclaration(node: ClassLikeDeclaration): ConstructorDeclaration | undefined { @@ -5876,7 +5888,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Qualify if the symbol from symbol table has same meaning as expected const shouldResolveAlias = (symbolFromSymbolTable.flags & SymbolFlags.Alias && !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)); symbolFromSymbolTable = shouldResolveAlias ? resolveAlias(symbolFromSymbolTable) : symbolFromSymbolTable; - const flags = shouldResolveAlias ? getAllSymbolFlags(symbolFromSymbolTable) : symbolFromSymbolTable.flags; + const flags = shouldResolveAlias ? getSymbolFlags(symbolFromSymbolTable) : symbolFromSymbolTable.flags; if (flags & meaning) { qualify = true; return true; @@ -8944,7 +8956,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isTypeOnlyNamespace(symbol: Symbol) { - return every(getNamespaceMembersForSerialization(symbol), m => !(getAllSymbolFlags(resolveSymbol(m)) & SymbolFlags.Value)); + return every(getNamespaceMembersForSerialization(symbol), m => !(getSymbolFlags(resolveSymbol(m)) & SymbolFlags.Value)); } function serializeModule(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) { @@ -11455,7 +11467,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { links.type = exportSymbol?.declarations && isDuplicatedCommonJSExport(exportSymbol.declarations) && symbol.declarations!.length ? getFlowTypeFromCommonJSExport(exportSymbol) : isDuplicatedCommonJSExport(symbol.declarations) ? autoType : declaredType ? declaredType - : getAllSymbolFlags(targetSymbol) & SymbolFlags.Value ? getTypeOfSymbol(targetSymbol) + : getSymbolFlags(targetSymbol) & SymbolFlags.Value ? getTypeOfSymbol(targetSymbol) : errorType; } return links.type; @@ -27818,9 +27830,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!canCollectSymbolAliasAccessabilityData) { return; } - if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && !getTypeOnlyAliasDeclaration(symbol, SymbolFlags.Value)) { + if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location)) { const target = resolveAlias(symbol); - if (getAllSymbolFlags(target) & (SymbolFlags.Value | SymbolFlags.ExportValue)) { + if (getSymbolFlags(symbol, /*excludeTypeOnlyMeanings*/ true) & (SymbolFlags.Value | SymbolFlags.ExportValue)) { // An alias resolving to a const enum cannot be elided if (1) 'isolatedModules' is enabled // (because the const enum value will not be inlined), or if (2) the alias is an export // of a const enum declaration that will be preserved. @@ -44276,7 +44288,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return; } - const targetFlags = getAllSymbolFlags(target); + const targetFlags = getSymbolFlags(target); const excludedMeanings = (symbol.flags & (SymbolFlags.Value | SymbolFlags.ExportValue) ? SymbolFlags.Value : 0) | (symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) | @@ -44478,7 +44490,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.moduleReference.kind !== SyntaxKind.ExternalModuleReference) { const target = resolveAlias(getSymbolOfDeclaration(node)); if (target !== unknownSymbol) { - const targetFlags = getAllSymbolFlags(target); + const targetFlags = getSymbolFlags(target); if (targetFlags & SymbolFlags.Value) { // Target is a value symbol, check that it is not hidden by a local declaration with the same name const moduleName = getFirstIdentifier(node.moduleReference); @@ -44635,7 +44647,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { markExportAsReferenced(node); } const target = symbol && (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); - if (!target || getAllSymbolFlags(target) & SymbolFlags.Value) { + if (!target || getSymbolFlags(target) & SymbolFlags.Value) { checkExpressionCached(node.propertyName || node.name); } } @@ -44691,7 +44703,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (sym) { markAliasReferenced(sym, id); // If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`) - if (getAllSymbolFlags(sym) & SymbolFlags.Value) { + if (getSymbolFlags(sym) & SymbolFlags.Value) { // However if it is a value, we need to check it's being used correctly checkExpressionCached(id); if (!isIllegalExportDefaultInCJS && !(node.flags & NodeFlags.Ambient) && compilerOptions.verbatimModuleSyntax && getTypeOnlyAliasDeclaration(sym, SymbolFlags.Value)) { @@ -46198,7 +46210,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function isValue(s: Symbol): boolean { s = resolveSymbol(s); - return s && !!(getAllSymbolFlags(s) & SymbolFlags.Value); + return s && !!(getSymbolFlags(s) & SymbolFlags.Value); } } @@ -46353,7 +46365,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: const symbol = getSymbolOfDeclaration(node as ImportClause | NamespaceImport | ImportSpecifier | ExportSpecifier); - return !!symbol && isAliasResolvedToValue(symbol) && !getTypeOnlyAliasDeclaration(symbol, SymbolFlags.Value); + return !!symbol && isAliasResolvedToValue(symbol, /*excludeTypeOnlyValues*/ true); case SyntaxKind.ExportDeclaration: const exportClause = (node as ExportDeclaration).exportClause; return !!exportClause && ( @@ -46379,7 +46391,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return isValue && node.moduleReference && !nodeIsMissing(node.moduleReference); } - function isAliasResolvedToValue(symbol: Symbol | undefined): boolean { + function isAliasResolvedToValue(symbol: Symbol | undefined, excludeTypeOnlyValues?: boolean): boolean { if (!symbol) { return false; } @@ -46389,7 +46401,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // const enums and modules that contain only const enums are not considered values from the emit perspective // unless 'preserveConstEnums' option is set to true - return !!((getAllSymbolFlags(target) ?? -1) & SymbolFlags.Value) && + return !!(getSymbolFlags(symbol, excludeTypeOnlyValues, /*excludeLocalMeanings*/ true) & SymbolFlags.Value) && (shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target)); } @@ -46407,7 +46419,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const target = getSymbolLinks(symbol).aliasTarget; if (target && getEffectiveModifierFlags(node) & ModifierFlags.Export && - getAllSymbolFlags(target) & SymbolFlags.Value && + getSymbolFlags(target) & SymbolFlags.Value && (shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target))) { // An `export import ... =` of a value symbol is always considered referenced return true; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 873554db782..99755607d36 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3814,8 +3814,8 @@ export type TypeOnlyImportDeclaration = export type TypeOnlyExportDeclaration = | ExportSpecifier & ({ readonly isTypeOnly: true } | { readonly parent: NamedExports & { readonly parent: ExportDeclaration & { readonly isTypeOnly: true } } }) - | ExportDeclaration & { readonly isTypeOnly: true } // export * from "mod" - | NamespaceExport & { readonly parent: ExportDeclaration & { readonly isTypeOnly: true } } // export * as ns from "mod" + | ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression } // export * from "mod" + | NamespaceExport & { readonly parent: ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression } } // export * as ns from "mod" ; export type TypeOnlyAliasDeclaration = TypeOnlyImportDeclaration | TypeOnlyExportDeclaration; @@ -5878,7 +5878,7 @@ export interface SymbolLinks { deferralParent?: Type; // Source union/intersection of a deferred type cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target typeOnlyDeclaration?: TypeOnlyAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs - typeOnlyExportStarMap?: Map<__String, ExportDeclaration & { readonly isTypeOnly: true }>; // Set on a module symbol when some of its exports were resolved through a 'export type * from "mod"' declaration + typeOnlyExportStarMap?: Map<__String, ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression }>; // Set on a module symbol when some of its exports were resolved through a 'export type * from "mod"' declaration typeOnlyExportStarName?: __String; // Set to the name of the symbol re-exported by an 'export type *' declaration, when different from the symbol name isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label diff --git a/src/testRunner/unittests/services/transpile.ts b/src/testRunner/unittests/services/transpile.ts index cd6414bdf33..ae05aaa9bcd 100644 --- a/src/testRunner/unittests/services/transpile.ts +++ b/src/testRunner/unittests/services/transpile.ts @@ -620,4 +620,16 @@ export * as alias from './file';`, { testVerbatimModuleSyntax: true } ); + + transpilesCorrectly("Preserves exported const merged with type-only import", ` + import fooValue from "./values"; + import type {Foo} from "./types"; + + const Foo: Foo = fooValue as any as Foo; + + export {Foo}; + `, { + options: { compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ESNext } }, + testVerbatimModuleSyntax: true + }); }); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 4571351e5a9..95422c57020 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5832,9 +5832,11 @@ declare namespace ts { }; }) | ExportDeclaration & { readonly isTypeOnly: true; + readonly moduleSpecifier: Expression; } | NamespaceExport & { readonly parent: ExportDeclaration & { readonly isTypeOnly: true; + readonly moduleSpecifier: Expression; }; }; type TypeOnlyAliasDeclaration = TypeOnlyImportDeclaration | TypeOnlyExportDeclaration; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 09abb27b970..404f94a1807 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1774,9 +1774,11 @@ declare namespace ts { }; }) | ExportDeclaration & { readonly isTypeOnly: true; + readonly moduleSpecifier: Expression; } | NamespaceExport & { readonly parent: ExportDeclaration & { readonly isTypeOnly: true; + readonly moduleSpecifier: Expression; }; }; type TypeOnlyAliasDeclaration = TypeOnlyImportDeclaration | TypeOnlyExportDeclaration; diff --git a/tests/baselines/reference/importElisionExportNonExportAndDefault.symbols b/tests/baselines/reference/importElisionExportNonExportAndDefault.symbols index cb6d6eed52e..d2f46dd5779 100644 --- a/tests/baselines/reference/importElisionExportNonExportAndDefault.symbols +++ b/tests/baselines/reference/importElisionExportNonExportAndDefault.symbols @@ -5,6 +5,7 @@ import MyFunction from "./MyComponent"; >MyFunction : Symbol(MyFunction, Decl(main.ts, 0, 6)) MyFunction({msg: "Hello World"}); +>MyFunction : Symbol(MyFunction, Decl(main.ts, 0, 6)) >msg : Symbol(msg, Decl(main.ts, 2, 12)) diff --git a/tests/baselines/reference/importEquals3.js b/tests/baselines/reference/importEquals3.js index d49e222c865..fa84a014660 100644 --- a/tests/baselines/reference/importEquals3.js +++ b/tests/baselines/reference/importEquals3.js @@ -33,7 +33,9 @@ exports.A = A; //// [b.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.x = void 0; +exports.x = exports.A = void 0; +var A = a.A; // Error +exports.A = A; var x = 0; exports.x = x; //// [c.js] diff --git a/tests/baselines/reference/namespaceImportTypeQuery2.js b/tests/baselines/reference/namespaceImportTypeQuery2.js new file mode 100644 index 00000000000..76be90d8beb --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery2.js @@ -0,0 +1,43 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery2.ts] //// + +//// [z.ts] +interface A {} +export type { A }; + +//// [a.ts] +import { A } from './z'; +const A = 0; +export { A }; +export class B {}; + +//// [b.ts] +import * as types from './a'; +let t: typeof types = { + A: undefined as any, // ok + B: undefined as any, +} + + +//// [z.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.B = exports.A = void 0; +var A = 0; +exports.A = A; +var B = /** @class */ (function () { + function B() { + } + return B; +}()); +exports.B = B; +; +//// [b.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var t = { + A: undefined, + B: undefined, +}; diff --git a/tests/baselines/reference/namespaceImportTypeQuery2.symbols b/tests/baselines/reference/namespaceImportTypeQuery2.symbols new file mode 100644 index 00000000000..f881c9fd8d8 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery2.symbols @@ -0,0 +1,39 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery2.ts] //// + +=== /z.ts === +interface A {} +>A : Symbol(A, Decl(z.ts, 0, 0)) + +export type { A }; +>A : Symbol(A, Decl(z.ts, 1, 13)) + +=== /a.ts === +import { A } from './z'; +>A : Symbol(A, Decl(a.ts, 0, 8), Decl(a.ts, 1, 5)) + +const A = 0; +>A : Symbol(A, Decl(a.ts, 0, 8), Decl(a.ts, 1, 5)) + +export { A }; +>A : Symbol(A, Decl(a.ts, 2, 8)) + +export class B {}; +>B : Symbol(B, Decl(a.ts, 2, 13)) + +=== /b.ts === +import * as types from './a'; +>types : Symbol(types, Decl(b.ts, 0, 6)) + +let t: typeof types = { +>t : Symbol(t, Decl(b.ts, 1, 3)) +>types : Symbol(types, Decl(b.ts, 0, 6)) + + A: undefined as any, // ok +>A : Symbol(A, Decl(b.ts, 1, 23)) +>undefined : Symbol(undefined) + + B: undefined as any, +>B : Symbol(B, Decl(b.ts, 2, 22)) +>undefined : Symbol(undefined) +} + diff --git a/tests/baselines/reference/namespaceImportTypeQuery2.types b/tests/baselines/reference/namespaceImportTypeQuery2.types new file mode 100644 index 00000000000..a1da638e79b --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery2.types @@ -0,0 +1,41 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery2.ts] //// + +=== /z.ts === +interface A {} +export type { A }; +>A : A + +=== /a.ts === +import { A } from './z'; +>A : 0 + +const A = 0; +>A : 0 +>0 : 0 + +export { A }; +>A : 0 + +export class B {}; +>B : B + +=== /b.ts === +import * as types from './a'; +>types : typeof types + +let t: typeof types = { +>t : typeof types +>types : typeof types +>{ A: undefined as any, // ok B: undefined as any,} : { A: any; B: any; } + + A: undefined as any, // ok +>A : any +>undefined as any : any +>undefined : undefined + + B: undefined as any, +>B : any +>undefined as any : any +>undefined : undefined +} + diff --git a/tests/baselines/reference/namespaceImportTypeQuery3.errors.txt b/tests/baselines/reference/namespaceImportTypeQuery3.errors.txt new file mode 100644 index 00000000000..d22ed64a2a5 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery3.errors.txt @@ -0,0 +1,18 @@ +/a.ts(1,24): error TS2307: Cannot find module './z' or its corresponding type declarations. + + +==== /a.ts (1 errors) ==== + import type { A } from './z'; // unresolved + ~~~~~ +!!! error TS2307: Cannot find module './z' or its corresponding type declarations. + const A = 0; + export { A }; + export class B {}; + +==== /b.ts (0 errors) ==== + import * as types from './a'; + let t: typeof types = { + A: undefined as any, // ok + B: undefined as any, + } + \ No newline at end of file diff --git a/tests/baselines/reference/namespaceImportTypeQuery3.js b/tests/baselines/reference/namespaceImportTypeQuery3.js new file mode 100644 index 00000000000..d206a9fc2c7 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery3.js @@ -0,0 +1,36 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery3.ts] //// + +//// [a.ts] +import type { A } from './z'; // unresolved +const A = 0; +export { A }; +export class B {}; + +//// [b.ts] +import * as types from './a'; +let t: typeof types = { + A: undefined as any, // ok + B: undefined as any, +} + + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.B = exports.A = void 0; +var A = 0; +exports.A = A; +var B = /** @class */ (function () { + function B() { + } + return B; +}()); +exports.B = B; +; +//// [b.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var t = { + A: undefined, + B: undefined, +}; diff --git a/tests/baselines/reference/namespaceImportTypeQuery3.symbols b/tests/baselines/reference/namespaceImportTypeQuery3.symbols new file mode 100644 index 00000000000..6f495340a41 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery3.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery3.ts] //// + +=== /a.ts === +import type { A } from './z'; // unresolved +>A : Symbol(A, Decl(a.ts, 0, 13), Decl(a.ts, 1, 5)) + +const A = 0; +>A : Symbol(A, Decl(a.ts, 0, 13), Decl(a.ts, 1, 5)) + +export { A }; +>A : Symbol(A, Decl(a.ts, 2, 8)) + +export class B {}; +>B : Symbol(B, Decl(a.ts, 2, 13)) + +=== /b.ts === +import * as types from './a'; +>types : Symbol(types, Decl(b.ts, 0, 6)) + +let t: typeof types = { +>t : Symbol(t, Decl(b.ts, 1, 3)) +>types : Symbol(types, Decl(b.ts, 0, 6)) + + A: undefined as any, // ok +>A : Symbol(A, Decl(b.ts, 1, 23)) +>undefined : Symbol(undefined) + + B: undefined as any, +>B : Symbol(B, Decl(b.ts, 2, 22)) +>undefined : Symbol(undefined) +} + diff --git a/tests/baselines/reference/namespaceImportTypeQuery3.types b/tests/baselines/reference/namespaceImportTypeQuery3.types new file mode 100644 index 00000000000..859888541b2 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery3.types @@ -0,0 +1,36 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery3.ts] //// + +=== /a.ts === +import type { A } from './z'; // unresolved +>A : any + +const A = 0; +>A : 0 +>0 : 0 + +export { A }; +>A : 0 + +export class B {}; +>B : B + +=== /b.ts === +import * as types from './a'; +>types : typeof types + +let t: typeof types = { +>t : typeof types +>types : typeof types +>{ A: undefined as any, // ok B: undefined as any,} : { A: any; B: any; } + + A: undefined as any, // ok +>A : any +>undefined as any : any +>undefined : undefined + + B: undefined as any, +>B : any +>undefined as any : any +>undefined : undefined +} + diff --git a/tests/baselines/reference/namespaceImportTypeQuery4.errors.txt b/tests/baselines/reference/namespaceImportTypeQuery4.errors.txt new file mode 100644 index 00000000000..bed29537a36 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery4.errors.txt @@ -0,0 +1,23 @@ +/a.ts(1,24): error TS2307: Cannot find module './z' or its corresponding type declarations. +/b.ts(3,3): error TS2322: Type '{ A: any; B: any; }' is not assignable to type 'typeof import("/a")'. + Object literal may only specify known properties, and 'A' does not exist in type 'typeof import("/a")'. + + +==== /a.ts (1 errors) ==== + import type { A } from './z'; // unresolved + ~~~~~ +!!! error TS2307: Cannot find module './z' or its corresponding type declarations. + type A = 0; + export { A }; + export class B {}; + +==== /b.ts (1 errors) ==== + import * as types from './a'; + let t: typeof types = { + A: undefined as any, // error + ~ +!!! error TS2322: Type '{ A: any; B: any; }' is not assignable to type 'typeof import("/a")'. +!!! error TS2322: Object literal may only specify known properties, and 'A' does not exist in type 'typeof import("/a")'. + B: undefined as any, + } + \ No newline at end of file diff --git a/tests/baselines/reference/namespaceImportTypeQuery4.js b/tests/baselines/reference/namespaceImportTypeQuery4.js new file mode 100644 index 00000000000..0390f537218 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery4.js @@ -0,0 +1,34 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery4.ts] //// + +//// [a.ts] +import type { A } from './z'; // unresolved +type A = 0; +export { A }; +export class B {}; + +//// [b.ts] +import * as types from './a'; +let t: typeof types = { + A: undefined as any, // error + B: undefined as any, +} + + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.B = void 0; +var B = /** @class */ (function () { + function B() { + } + return B; +}()); +exports.B = B; +; +//// [b.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var t = { + A: undefined, + B: undefined, +}; diff --git a/tests/baselines/reference/namespaceImportTypeQuery4.symbols b/tests/baselines/reference/namespaceImportTypeQuery4.symbols new file mode 100644 index 00000000000..a5408406310 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery4.symbols @@ -0,0 +1,32 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery4.ts] //// + +=== /a.ts === +import type { A } from './z'; // unresolved +>A : Symbol(A, Decl(a.ts, 0, 13), Decl(a.ts, 0, 29)) + +type A = 0; +>A : Symbol(A, Decl(a.ts, 0, 13), Decl(a.ts, 0, 29)) + +export { A }; +>A : Symbol(A, Decl(a.ts, 2, 8)) + +export class B {}; +>B : Symbol(B, Decl(a.ts, 2, 13)) + +=== /b.ts === +import * as types from './a'; +>types : Symbol(types, Decl(b.ts, 0, 6)) + +let t: typeof types = { +>t : Symbol(t, Decl(b.ts, 1, 3)) +>types : Symbol(types, Decl(b.ts, 0, 6)) + + A: undefined as any, // error +>A : Symbol(A, Decl(b.ts, 1, 23)) +>undefined : Symbol(undefined) + + B: undefined as any, +>B : Symbol(B, Decl(b.ts, 2, 22)) +>undefined : Symbol(undefined) +} + diff --git a/tests/baselines/reference/namespaceImportTypeQuery4.types b/tests/baselines/reference/namespaceImportTypeQuery4.types new file mode 100644 index 00000000000..6a13c1a8f01 --- /dev/null +++ b/tests/baselines/reference/namespaceImportTypeQuery4.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery4.ts] //// + +=== /a.ts === +import type { A } from './z'; // unresolved +>A : 0 + +type A = 0; +>A : 0 + +export { A }; +>A : any + +export class B {}; +>B : B + +=== /b.ts === +import * as types from './a'; +>types : typeof types + +let t: typeof types = { +>t : typeof types +>types : typeof types +>{ A: undefined as any, // error B: undefined as any,} : { A: any; B: any; } + + A: undefined as any, // error +>A : any +>undefined as any : any +>undefined : undefined + + B: undefined as any, +>B : any +>undefined as any : any +>undefined : undefined +} + diff --git a/tests/baselines/reference/transpile/Preserves exported const merged with type-only import (verbatimModuleSyntax=true).js b/tests/baselines/reference/transpile/Preserves exported const merged with type-only import (verbatimModuleSyntax=true).js new file mode 100644 index 00000000000..c1a35b90eb2 --- /dev/null +++ b/tests/baselines/reference/transpile/Preserves exported const merged with type-only import (verbatimModuleSyntax=true).js @@ -0,0 +1,4 @@ +import fooValue from "./values"; +const Foo = fooValue; +export { Foo }; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Preserves exported const merged with type-only import (verbatimModuleSyntax=true).oldTranspile.js b/tests/baselines/reference/transpile/Preserves exported const merged with type-only import (verbatimModuleSyntax=true).oldTranspile.js new file mode 100644 index 00000000000..c1a35b90eb2 --- /dev/null +++ b/tests/baselines/reference/transpile/Preserves exported const merged with type-only import (verbatimModuleSyntax=true).oldTranspile.js @@ -0,0 +1,4 @@ +import fooValue from "./values"; +const Foo = fooValue; +export { Foo }; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Preserves exported const merged with type-only import.js b/tests/baselines/reference/transpile/Preserves exported const merged with type-only import.js new file mode 100644 index 00000000000..c1a35b90eb2 --- /dev/null +++ b/tests/baselines/reference/transpile/Preserves exported const merged with type-only import.js @@ -0,0 +1,4 @@ +import fooValue from "./values"; +const Foo = fooValue; +export { Foo }; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Preserves exported const merged with type-only import.oldTranspile.js b/tests/baselines/reference/transpile/Preserves exported const merged with type-only import.oldTranspile.js new file mode 100644 index 00000000000..c1a35b90eb2 --- /dev/null +++ b/tests/baselines/reference/transpile/Preserves exported const merged with type-only import.oldTranspile.js @@ -0,0 +1,4 @@ +import fooValue from "./values"; +const Foo = fooValue; +export { Foo }; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/typeOnlyMerge3.js b/tests/baselines/reference/typeOnlyMerge3.js index 21c0e67554a..44e0443fe5f 100644 --- a/tests/baselines/reference/typeOnlyMerge3.js +++ b/tests/baselines/reference/typeOnlyMerge3.js @@ -25,13 +25,15 @@ function A() { } //// [b.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.A = void 0; var A; (function (A) { A.displayName = "A"; -})(A || (A = {})); +})(A || (exports.A = A = {})); //// [c.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +var b_1 = require("./b"); A; A.displayName; A(); diff --git a/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery2.ts b/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery2.ts new file mode 100644 index 00000000000..5ff13df84af --- /dev/null +++ b/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery2.ts @@ -0,0 +1,16 @@ +// @Filename: /z.ts +interface A {} +export type { A }; + +// @Filename: /a.ts +import { A } from './z'; +const A = 0; +export { A }; +export class B {}; + +// @Filename: /b.ts +import * as types from './a'; +let t: typeof types = { + A: undefined as any, // ok + B: undefined as any, +} diff --git a/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery3.ts b/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery3.ts new file mode 100644 index 00000000000..2e564378a6d --- /dev/null +++ b/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery3.ts @@ -0,0 +1,12 @@ +// @Filename: /a.ts +import type { A } from './z'; // unresolved +const A = 0; +export { A }; +export class B {}; + +// @Filename: /b.ts +import * as types from './a'; +let t: typeof types = { + A: undefined as any, // ok + B: undefined as any, +} diff --git a/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery4.ts b/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery4.ts new file mode 100644 index 00000000000..80fefc23ad8 --- /dev/null +++ b/tests/cases/conformance/externalModules/typeOnly/namespaceImportTypeQuery4.ts @@ -0,0 +1,12 @@ +// @Filename: /a.ts +import type { A } from './z'; // unresolved +type A = 0; +export { A }; +export class B {}; + +// @Filename: /b.ts +import * as types from './a'; +let t: typeof types = { + A: undefined as any, // error + B: undefined as any, +}