diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a713cf6c83ac4..57cca12c38c29 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -541,6 +541,7 @@ import { isExternalModuleIndicator, isExternalModuleNameRelative, isExternalModuleReference, + isExternalModuleSymbol, isExternalOrCommonJsModule, isForInOrOfStatement, isForInStatement, @@ -8975,7 +8976,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const parentSymbol = nodeSymbol && isSymbolAccessible(nodeSymbol, context.enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible && lookupSymbolChain(nodeSymbol, context, meaning, /*yieldModuleSymbol*/ true)[0]; - if (parentSymbol && parentSymbol.flags & SymbolFlags.Module) { + if (parentSymbol && isExternalModuleSymbol(parentSymbol)) { name = getSpecifierForModuleSymbol(parentSymbol, context); } else { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 16a092532bd45..81cfddfc0578a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -632,6 +632,15 @@ export function isTransientSymbol(symbol: Symbol): symbol is TransientSymbol { return (symbol.flags & SymbolFlags.Transient) !== 0; } +/** + * True if the symbol is for an external module, as opposed to a namespace. + * + * @internal + */ +export function isExternalModuleSymbol(moduleSymbol: Symbol): boolean { + return !!(moduleSymbol.flags & SymbolFlags.Module) && (moduleSymbol.escapedName as string).charCodeAt(0) === CharacterCodes.doubleQuote; +} + const stringWriter = createSingleLineStringWriter(); function createSingleLineStringWriter(): EmitTextWriter { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index abfe9f908fcba..b5e726b912e38 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2408,15 +2408,6 @@ export function isTypeKeywordTokenOrIdentifier(node: Node) { return isTypeKeywordToken(node) || isIdentifier(node) && node.text === "type"; } -/** - * True if the symbol is for an external module, as opposed to a namespace. - * - * @internal - */ -export function isExternalModuleSymbol(moduleSymbol: Symbol): boolean { - return !!(moduleSymbol.flags & SymbolFlags.Module) && moduleSymbol.name.charCodeAt(0) === CharacterCodes.doubleQuote; -} - /** * Returns `true` the first time it encounters a node and `false` afterwards. * diff --git a/tests/baselines/reference/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.errors.txt b/tests/baselines/reference/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.errors.txt new file mode 100644 index 0000000000000..5e1769bc3646f --- /dev/null +++ b/tests/baselines/reference/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.errors.txt @@ -0,0 +1,37 @@ +/types.js(3,21): error TS2304: Cannot find name 'Keyword'. +/types.js(3,30): error TS2304: Cannot find name 'ParamValueTyped'. + + +==== /contractHelper.d.ts (0 errors) ==== + export function handleParamGovernance(zcf: any): { + publicMixin: { + getGovernedParams: () => globalThis.ERef; + }; + }; + +==== /exported.d.ts (0 errors) ==== + type _ERef = T | Promise; + import { ParamStateRecord as _ParamStateRecord } from './types.js'; + declare global { + // @ts-ignore TS2666 + export { + _ERef as ERef, + _ParamStateRecord as ParamStateRecord, + }; + } + +==== /types.js (2 errors) ==== + export {}; + /** + * @typedef {Record} ParamStateRecord a Record containing + ~~~~~~~ +!!! error TS2304: Cannot find name 'Keyword'. + ~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'ParamValueTyped'. + * keyword pairs with descriptions of parameters under governance. + */ + +==== /index.js (0 errors) ==== + import { handleParamGovernance } from './contractHelper.js'; + export const blah = handleParamGovernance({}); + \ No newline at end of file diff --git a/tests/baselines/reference/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.js b/tests/baselines/reference/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.js new file mode 100644 index 0000000000000..45784a12d5086 --- /dev/null +++ b/tests/baselines/reference/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.js @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.ts] //// + +//// [contractHelper.d.ts] +export function handleParamGovernance(zcf: any): { + publicMixin: { + getGovernedParams: () => globalThis.ERef; + }; +}; + +//// [exported.d.ts] +type _ERef = T | Promise; +import { ParamStateRecord as _ParamStateRecord } from './types.js'; +declare global { + // @ts-ignore TS2666 + export { + _ERef as ERef, + _ParamStateRecord as ParamStateRecord, + }; +} + +//// [types.js] +export {}; +/** + * @typedef {Record} ParamStateRecord a Record containing + * keyword pairs with descriptions of parameters under governance. + */ + +//// [index.js] +import { handleParamGovernance } from './contractHelper.js'; +export const blah = handleParamGovernance({}); + + + + +//// [types.d.ts] +/** + * a Record containing + * keyword pairs with descriptions of parameters under governance. + */ +export type ParamStateRecord = Record; +//// [index.d.ts] +export const blah: { + publicMixin: { + getGovernedParams: () => globalThis.ERef; + }; +}; diff --git a/tests/cases/compiler/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.ts b/tests/cases/compiler/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.ts new file mode 100644 index 0000000000000..faccc6f97164b --- /dev/null +++ b/tests/cases/compiler/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.ts @@ -0,0 +1,34 @@ +// @checkJs: true +// @declaration: true +// @module: preserve +// @emitDeclarationOnly: true +// @noTypesAndSymbols: true + +// @Filename: /contractHelper.d.ts +export function handleParamGovernance(zcf: any): { + publicMixin: { + getGovernedParams: () => globalThis.ERef; + }; +}; + +// @Filename: /exported.d.ts +type _ERef = T | Promise; +import { ParamStateRecord as _ParamStateRecord } from './types.js'; +declare global { + // @ts-ignore TS2666 + export { + _ERef as ERef, + _ParamStateRecord as ParamStateRecord, + }; +} + +// @Filename: /types.js +export {}; +/** + * @typedef {Record} ParamStateRecord a Record containing + * keyword pairs with descriptions of parameters under governance. + */ + +// @Filename: /index.js +import { handleParamGovernance } from './contractHelper.js'; +export const blah = handleParamGovernance({});