@@ -2637,6 +2637,11 @@ namespace ts {
26372637 return usageMode === ModuleKind.ESNext && targetMode === ModuleKind.CommonJS;
26382638 }
26392639
2640+ function isOnlyImportedAsDefault(usage: Expression) {
2641+ const usageMode = getUsageModeForExpression(usage);
2642+ return usageMode === ModuleKind.ESNext && endsWith((usage as StringLiteralLike).text, Extension.Json);
2643+ }
2644+
26402645 function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean, usage: Expression) {
26412646 const usageMode = file && getUsageModeForExpression(usage);
26422647 if (file && usageMode !== undefined) {
@@ -2688,8 +2693,9 @@ namespace ts {
26882693 }
26892694
26902695 const file = moduleSymbol.declarations?.find(isSourceFile);
2696+ const hasDefaultOnly = isOnlyImportedAsDefault(node.parent.moduleSpecifier);
26912697 const hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier);
2692- if (!exportDefaultSymbol && !hasSyntheticDefault) {
2698+ if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly ) {
26932699 if (hasExportAssignmentSymbol(moduleSymbol)) {
26942700 const compilerOptionName = moduleKind >= ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop";
26952701 const exportEqualsSymbol = moduleSymbol.exports!.get(InternalSymbolName.ExportEquals);
@@ -2708,7 +2714,7 @@ namespace ts {
27082714 reportNonDefaultExport(moduleSymbol, node);
27092715 }
27102716 }
2711- else if (hasSyntheticDefault) {
2717+ else if (hasSyntheticDefault || hasDefaultOnly ) {
27122718 // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present
27132719 const resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
27142720 markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false);
@@ -2840,7 +2846,7 @@ namespace ts {
28402846 let symbolFromModule = getExportOfModule(targetSymbol, name, specifier, dontResolveAlias);
28412847 if (symbolFromModule === undefined && name.escapedText === InternalSymbolName.Default) {
28422848 const file = moduleSymbol.declarations?.find(isSourceFile);
2843- if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, moduleSpecifier)) {
2849+ if (isOnlyImportedAsDefault(moduleSpecifier) || canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, moduleSpecifier)) {
28442850 symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
28452851 }
28462852 }
@@ -3449,6 +3455,9 @@ namespace ts {
34493455 if (isSyncImport && sourceFile.impliedNodeFormat === ModuleKind.ESNext) {
34503456 error(errorNode, Diagnostics.Module_0_cannot_be_imported_using_this_construct_The_specifier_only_resolves_to_an_ES_module_which_cannot_be_imported_synchronously_Use_dynamic_import_instead, moduleReference);
34513457 }
3458+ if (mode === ModuleKind.ESNext && compilerOptions.resolveJsonModule && resolvedModule.extension === Extension.Json) {
3459+ error(errorNode, Diagnostics.JSON_imports_are_experimental_in_ES_module_mode_imports);
3460+ }
34523461 }
34533462 // merged symbol is module declaration symbol combined with all augmentations
34543463 return getMergedSymbol(sourceFile.symbol);
@@ -3611,39 +3620,51 @@ namespace ts {
36113620 return symbol;
36123621 }
36133622
3614- if (getESModuleInterop(compilerOptions)) {
3615- const referenceParent = referencingLocation.parent;
3616- if (
3617- (isImportDeclaration(referenceParent) && getNamespaceDeclarationNode(referenceParent)) ||
3618- isImportCall(referenceParent)
3619- ) {
3620- const type = getTypeOfSymbol(symbol);
3623+ const referenceParent = referencingLocation.parent;
3624+ if (
3625+ (isImportDeclaration(referenceParent) && getNamespaceDeclarationNode(referenceParent)) ||
3626+ isImportCall(referenceParent)
3627+ ) {
3628+ const reference = isImportCall(referenceParent) ? referenceParent.arguments[0] : referenceParent.moduleSpecifier;
3629+ const type = getTypeOfSymbol(symbol);
3630+ const defaultOnlyType = getTypeWithSyntheticDefaultOnly(type, symbol, moduleSymbol!, reference);
3631+ if (defaultOnlyType) {
3632+ return cloneTypeAsModuleType(symbol, defaultOnlyType, referenceParent);
3633+ }
3634+
3635+ if (getESModuleInterop(compilerOptions)) {
36213636 let sigs = getSignaturesOfStructuredType(type, SignatureKind.Call);
36223637 if (!sigs || !sigs.length) {
36233638 sigs = getSignaturesOfStructuredType(type, SignatureKind.Construct);
36243639 }
3625- if (sigs && sigs.length) {
3626- const moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol!, isImportCall(referenceParent) ? referenceParent.arguments[0] : referenceParent.moduleSpecifier);
3627- // Create a new symbol which has the module's type less the call and construct signatures
3628- const result = createSymbol(symbol.flags, symbol.escapedName);
3629- result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
3630- result.parent = symbol.parent;
3631- result.target = symbol;
3632- result.originatingImport = referenceParent;
3633- if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration;
3634- if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true;
3635- if (symbol.members) result.members = new Map(symbol.members);
3636- if (symbol.exports) result.exports = new Map(symbol.exports);
3637- const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above
3638- result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.indexInfos);
3639- return result;
3640+ if ((sigs && sigs.length) || getPropertyOfType(type, InternalSymbolName.Default)) {
3641+ const moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol!, reference);
3642+ return cloneTypeAsModuleType(symbol, moduleType, referenceParent);
36403643 }
36413644 }
36423645 }
36433646 }
36443647 return symbol;
36453648 }
36463649
3650+ /**
3651+ * Create a new symbol which has the module's type less the call and construct signatures
3652+ */
3653+ function cloneTypeAsModuleType(symbol: Symbol, moduleType: Type, referenceParent: ImportDeclaration | ImportCall) {
3654+ const result = createSymbol(symbol.flags, symbol.escapedName);
3655+ result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
3656+ result.parent = symbol.parent;
3657+ result.target = symbol;
3658+ result.originatingImport = referenceParent;
3659+ if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration;
3660+ if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true;
3661+ if (symbol.members) result.members = new Map(symbol.members);
3662+ if (symbol.exports) result.exports = new Map(symbol.exports);
3663+ const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above
3664+ result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.indexInfos);
3665+ return result;
3666+ }
3667+
36473668 function hasExportAssignmentSymbol(moduleSymbol: Symbol): boolean {
36483669 return moduleSymbol.exports!.get(InternalSymbolName.ExportEquals) !== undefined;
36493670 }
@@ -31007,27 +31028,47 @@ namespace ts {
3100731028 if (moduleSymbol) {
3100831029 const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true, /*suppressUsageError*/ false);
3100931030 if (esModuleSymbol) {
31010- return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier));
31031+ return createPromiseReturnType(node,
31032+ getTypeWithSyntheticDefaultOnly(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier) ||
31033+ getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier)
31034+ );
3101131035 }
3101231036 }
3101331037 return createPromiseReturnType(node, anyType);
3101431038 }
3101531039
31040+ function createDefaultPropertyWrapperForModule(symbol: Symbol, originalSymbol: Symbol, anonymousSymbol?: Symbol | undefined) {
31041+ const memberTable = createSymbolTable();
31042+ const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default);
31043+ newSymbol.parent = originalSymbol;
31044+ newSymbol.nameType = getStringLiteralType("default");
31045+ newSymbol.target = resolveSymbol(symbol);
31046+ memberTable.set(InternalSymbolName.Default, newSymbol);
31047+ return createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, emptyArray);
31048+ }
31049+
31050+ function getTypeWithSyntheticDefaultOnly(type: Type, symbol: Symbol, originalSymbol: Symbol, moduleSpecifier: Expression) {
31051+ const hasDefaultOnly = isOnlyImportedAsDefault(moduleSpecifier);
31052+ if (hasDefaultOnly && type && !isErrorType(type)) {
31053+ const synthType = type as SyntheticDefaultModuleType;
31054+ if (!synthType.defaultOnlyType) {
31055+ const type = createDefaultPropertyWrapperForModule(symbol, originalSymbol);
31056+ synthType.defaultOnlyType = type;
31057+ }
31058+ return synthType.defaultOnlyType;
31059+ }
31060+ return undefined;
31061+ }
31062+
3101631063 function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol, originalSymbol: Symbol, moduleSpecifier: Expression): Type {
3101731064 if (allowSyntheticDefaultImports && type && !isErrorType(type)) {
3101831065 const synthType = type as SyntheticDefaultModuleType;
3101931066 if (!synthType.syntheticType) {
3102031067 const file = originalSymbol.declarations?.find(isSourceFile);
3102131068 const hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false, moduleSpecifier);
3102231069 if (hasSyntheticDefault) {
31023- const memberTable = createSymbolTable();
31024- const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default);
31025- newSymbol.parent = originalSymbol;
31026- newSymbol.nameType = getStringLiteralType("default");
31027- newSymbol.target = resolveSymbol(symbol);
31028- memberTable.set(InternalSymbolName.Default, newSymbol);
3102931070 const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
31030- const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, emptyArray );
31071+ const defaultContainingObject = createDefaultPropertyWrapperForModule(symbol, originalSymbol, anonymousSymbol );
3103131072 anonymousSymbol.type = defaultContainingObject;
3103231073 synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
3103331074 }
0 commit comments