diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 273f10f375f25..9dfb79bda1ee4 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -585,10 +585,8 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string if (resolutionMode === ModuleKind.ESNext && (ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext)) { features |= NodeResolutionFeatures.EsmMode; } - // true: "import" / false: "require" / undefined: default based on settings - const useImportCondition = resolutionMode === ModuleKind.ESNext || (resolutionMode !== undefined ? false : undefined); const conditions = (features & NodeResolutionFeatures.Exports) - ? getConditions(options, useImportCondition) + ? getConditions(options, resolutionMode) : []; const diagnostics: Diagnostic[] = []; const moduleResolutionState: ModuleResolutionState = { @@ -744,16 +742,13 @@ function getNodeResolutionFeatures(options: CompilerOptions) { return features; } -/** - * @param overrideResolutionModeAttribute - * @internal - */ -export function getConditions(options: CompilerOptions, esmMode?: boolean) { +/** @internal */ +export function getConditions(options: CompilerOptions, resolutionMode?: ResolutionMode) { const moduleResolution = getEmitModuleResolutionKind(options); - if (esmMode === undefined) { + if (resolutionMode === undefined) { if (moduleResolution === ModuleResolutionKind.Bundler) { // bundler always uses `import` unless explicitly overridden - esmMode ??= moduleResolution === ModuleResolutionKind.Bundler; + resolutionMode = ModuleKind.ESNext; } else if (moduleResolution === ModuleResolutionKind.Node10) { // node10 does not support package.json imports/exports without @@ -764,7 +759,7 @@ export function getConditions(options: CompilerOptions, esmMode?: boolean) { } // conditions are only used by the node16/nodenext/bundler resolvers - there's no priority order in the list, // it's essentially a set (priority is determined by object insertion order in the object we look at). - const conditions = esmMode + const conditions = resolutionMode === ModuleKind.ESNext ? ["import"] : ["require"]; if (!options.noDtsResolution) { @@ -1439,13 +1434,13 @@ export function resolveModuleName(moduleName: string, containingFile: string, co result = nodeNextModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode); break; case ModuleResolutionKind.Node10: - result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode ? getConditions(compilerOptions, resolutionMode === ModuleKind.ESNext) : undefined); + result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode ? getConditions(compilerOptions, resolutionMode) : undefined); break; case ModuleResolutionKind.Classic: result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference); break; case ModuleResolutionKind.Bundler: - result = bundlerModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode ? getConditions(compilerOptions, resolutionMode === ModuleKind.ESNext) : undefined); + result = bundlerModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode ? getConditions(compilerOptions, resolutionMode) : undefined); break; default: return Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`); @@ -1813,7 +1808,7 @@ function nodeModuleNameResolverWorker( compilerOptions, moduleResolution === ModuleResolutionKind.Bundler || moduleResolution === ModuleResolutionKind.Node10 ? undefined - : !!(features & NodeResolutionFeatures.EsmMode), + : (features & NodeResolutionFeatures.EsmMode) ? ModuleKind.ESNext : ModuleKind.CommonJS, ); const diagnostics: Diagnostic[] = []; @@ -2225,7 +2220,7 @@ export function getEntrypointsFromPackageJsonInfo( if (features & NodeResolutionFeatures.Exports && packageJsonInfo.contents.packageJsonContent.exports) { const conditionSets = deduplicate( - [getConditions(options, /*esmMode*/ true), getConditions(options, /*esmMode*/ false)], + [getConditions(options, ModuleKind.ESNext), getConditions(options, ModuleKind.CommonJS)], arrayIsEqualTo, ); for (const conditions of conditionSets) { diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 97e8e6b5edc81..a59fc09a674ef 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -992,7 +992,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan // use the actual directory name, so don't look at `packageJsonContent.name` here. const nodeModulesDirectoryName = packageRootPath.substring(parts.topLevelPackageNameIndex + 1); const packageName = getPackageNameFromTypesPackageName(nodeModulesDirectoryName); - const conditions = getConditions(options, importMode === ModuleKind.ESNext); + const conditions = getConditions(options, importMode); const fromExports = packageJsonContent.exports ? tryGetModuleNameFromExports(options, path, packageRootPath, packageName, packageJsonContent.exports, conditions) : undefined; diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 47ec1126728d0..b5c28a312d9ec 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -96,7 +96,6 @@ import { LiteralTypeNode, mapDefined, MapLike, - ModuleKind, moduleResolutionUsesNodeModules, ModuleSpecifierEnding, moduleSpecifiers, @@ -952,7 +951,7 @@ function getCompletionEntriesForNonRelativeModules( } const keys = getOwnKeys(exports); const fragmentSubpath = components.join("/") + (components.length && hasTrailingDirectorySeparator(fragment) ? "/" : ""); - const conditions = getConditions(compilerOptions, mode === ModuleKind.ESNext); + const conditions = getConditions(compilerOptions, mode); addCompletionEntriesFromPathsOrExports( result, fragmentSubpath, diff --git a/tests/baselines/reference/declarationEmitBundlerConditions.js b/tests/baselines/reference/declarationEmitBundlerConditions.js new file mode 100644 index 0000000000000..89f37accc091f --- /dev/null +++ b/tests/baselines/reference/declarationEmitBundlerConditions.js @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/declarationEmitBundlerConditions.ts] //// + +//// [package.json] +{ + "name": "pkg", + "type": "module", + "exports": { + ".": { + "import": "./index.js", + "require": "./index.cjs" + } + } +} + +//// [index.d.ts] +export declare class C { + private p; +} + +//// [index.d.cts] +export {}; + +//// [makeC.ts] +import { C } from "pkg"; +export function makeC() { + return new C(); +} + +//// [index.ts] +import { makeC } from "./makeC"; +export const c = makeC(); + + + + +//// [makeC.d.ts] +import { C } from "pkg"; +export declare function makeC(): C; +//// [index.d.ts] +export declare const c: import("pkg").C; diff --git a/tests/cases/compiler/declarationEmitBundlerConditions.ts b/tests/cases/compiler/declarationEmitBundlerConditions.ts new file mode 100644 index 0000000000000..2cfcdbf2f862b --- /dev/null +++ b/tests/cases/compiler/declarationEmitBundlerConditions.ts @@ -0,0 +1,35 @@ +// @module: esnext +// @moduleResolution: bundler +// @declaration: true +// @emitDeclarationOnly: true +// @noTypesAndSymbols: true + +// @Filename: /node_modules/pkg/package.json +{ + "name": "pkg", + "type": "module", + "exports": { + ".": { + "import": "./index.js", + "require": "./index.cjs" + } + } +} + +// @Filename: /node_modules/pkg/index.d.ts +export declare class C { + private p; +} + +// @Filename: /node_modules/pkg/index.d.cts +export {}; + +// @Filename: /makeC.ts +import { C } from "pkg"; +export function makeC() { + return new C(); +} + +// @Filename: /index.ts +import { makeC } from "./makeC"; +export const c = makeC();