From ef0171aee7e069b5461a7840df648a726f977df6 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 20 Nov 2023 15:33:20 -0800 Subject: [PATCH 01/13] Add `--moduleFormatInterop` option --- src/compiler/commandLineParser.ts | 13 +++++++++++++ src/compiler/diagnosticMessages.json | 8 ++++++++ src/compiler/types.ts | 9 +++++++++ src/compiler/utilities.ts | 18 ++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 6d29b82bed704..3aac4cd676729 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -82,6 +82,7 @@ import { mapIterator, MapLike, ModuleDetectionKind, + ModuleFormatInteropKind, ModuleKind, ModuleResolutionKind, NewLineKind, @@ -1154,6 +1155,18 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [ category: Diagnostics.Modules, description: Diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports, }, + { + name: "moduleFormatInterop", + type: new Map(Object.entries({ + babel: ModuleFormatInteropKind.Bundler, + bundlernode: ModuleFormatInteropKind.BundlerNode, + node16: ModuleFormatInteropKind.Node16, + nodenext: ModuleFormatInteropKind.NodeNext, + })), + category: Diagnostics.Modules, + description: Diagnostics.Specify_the_target_runtime_s_rules_for_ESM_CommonJS_interoperation, + defaultValueDescription: Diagnostics.node16_when_module_is_node16_nodenext_when_module_is_nodenext_bundler_otherwise, + }, // Source Maps { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 1979557243abb..2dedc9cc4de54 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -6235,6 +6235,10 @@ "category": "Message", "code": 6804 }, + "Specify the target runtime's rules for ESM-CommonJS interoperation.": { + "category": "Message", + "code": 6805 + }, "one of:": { "category": "Message", @@ -6364,6 +6368,10 @@ "category": "Error", "code": 6931 }, + "'node16' when 'module' is 'node16'; 'nodenext' when 'module' is 'nodenext'; 'bundler' otherwise.": { + "category": "Message", + "code": 6932 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0376471ced20b..762e99fb95604 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -7174,6 +7174,7 @@ export interface CompilerOptions { mapRoot?: string; maxNodeModuleJsDepth?: number; module?: ModuleKind; + moduleFormatInterop?: ModuleFormatInteropKind; moduleResolution?: ModuleResolutionKind; moduleSuffixes?: string[]; moduleDetection?: ModuleDetectionKind; @@ -7297,6 +7298,14 @@ export enum ModuleKind { NodeNext = 199, } +export enum ModuleFormatInteropKind { + Bundler = 1, + BundlerNode = 2, + + Node16 = 100, + NodeNext = 199, +} + export const enum JsxEmit { None = 0, Preserve = 1, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 843249e4bba29..9fb9c1d6b6945 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -402,6 +402,8 @@ import { ModuleBlock, ModuleDeclaration, ModuleDetectionKind, + ModuleFormatDetectionKind, + ModuleFormatInteropKind, ModuleKind, ModuleResolutionKind, moduleResolutionOptionDeclarations, @@ -8659,6 +8661,22 @@ export const computedOptions = createComputedCompilerOptions({ computedOptions.module.computeValue(compilerOptions) === ModuleKind.NodeNext ? ModuleDetectionKind.Force : ModuleDetectionKind.Auto); }, }, + moduleFormatInterop: { + dependencies: ["module", "target"], + computeValue: (compilerOptions): ModuleFormatInteropKind => { + if (compilerOptions.moduleFormatInterop !== undefined) { + return compilerOptions.moduleFormatInterop; + } + switch (computedOptions.module.computeValue(compilerOptions)) { + case ModuleKind.Node16: + return ModuleFormatInteropKind.Node16; + case ModuleKind.NodeNext: + return ModuleFormatInteropKind.NodeNext; + default: + return ModuleFormatInteropKind.Bundler; + } + }, + }, isolatedModules: { dependencies: ["verbatimModuleSyntax"], computeValue: compilerOptions => { From 99148b9f9afe3d6f255f6b4dc9556c77f1f05f55 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 21 Nov 2023 10:24:35 -0800 Subject: [PATCH 02/13] Reference moduleFormatInterop instead of moduleResolution to control require(esm) error --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ed1fb6a057502..f84813cbdf31c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5009,6 +5009,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { (isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal; const mode = contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : currentSourceFile.impliedNodeFormat; const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); + const moduleFormatInterop = getModuleFormatInteropKind(compilerOptions); const resolvedModule = host.getResolvedModule(currentSourceFile, moduleReference, mode)?.resolvedModule; const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule, currentSourceFile); const sourceFile = resolvedModule @@ -5044,7 +5045,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) { errorOnImplicitAnyModule(/*isError*/ false, errorNode, currentSourceFile, mode, resolvedModule, moduleReference); } - if (moduleResolutionKind === ModuleResolutionKind.Node16 || moduleResolutionKind === ModuleResolutionKind.NodeNext) { + if (moduleFormatInterop === ModuleFormatInteropKind.Node16 || moduleFormatInterop === ModuleFormatInteropKind.NodeNext) { const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration); const overrideHost = findAncestor(location, l => isImportTypeNode(l) || isExportDeclaration(l) || isImportDeclaration(l)) as ImportTypeNode | ImportDeclaration | ExportDeclaration | undefined; // An override clause will take effect for type-only imports and import types, and allows importing the types across formats, regardless of From b94509a4773a3673397b99354449af16059c770b Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 20 Nov 2023 16:51:06 -0800 Subject: [PATCH 03/13] Add test demonstrating interop for esbuild and webpack --- .../reference/esbuildInterop.errors.txt | 26 +++++++++++++++++ tests/baselines/reference/esbuildInterop.js | 28 +++++++++++++++++++ .../reference/esbuildInterop.symbols | 23 +++++++++++++++ .../baselines/reference/esbuildInterop.types | 27 ++++++++++++++++++ .../conformance/module/esbuildInterop.ts | 25 +++++++++++++++++ 5 files changed, 129 insertions(+) create mode 100644 tests/baselines/reference/esbuildInterop.errors.txt create mode 100644 tests/baselines/reference/esbuildInterop.js create mode 100644 tests/baselines/reference/esbuildInterop.symbols create mode 100644 tests/baselines/reference/esbuildInterop.types create mode 100644 tests/cases/conformance/module/esbuildInterop.ts diff --git a/tests/baselines/reference/esbuildInterop.errors.txt b/tests/baselines/reference/esbuildInterop.errors.txt new file mode 100644 index 0000000000000..8f8d5f72ad359 --- /dev/null +++ b/tests/baselines/reference/esbuildInterop.errors.txt @@ -0,0 +1,26 @@ +/index.ts(2,5): error TS2339: Property 'toLowerCase' does not exist on type 'typeof import("/node_modules/dep/index")'. + + +==== /node_modules/dep/package.json (0 errors) ==== + { + "name": "dep", + "version": "1.0.0", + "main": "index.js" + } + +==== /node_modules/dep/index.d.ts (0 errors) ==== + declare const _default: string; + export default _default; + +==== /package.json (0 errors) ==== + { + "type": "module" + } + +==== /index.ts (1 errors) ==== + import dep from "dep"; + dep.toLowerCase(); // Error + ~~~~~~~~~~~ +!!! error TS2339: Property 'toLowerCase' does not exist on type 'typeof import("/node_modules/dep/index")'. + dep.default.toLowerCase(); // Ok + \ No newline at end of file diff --git a/tests/baselines/reference/esbuildInterop.js b/tests/baselines/reference/esbuildInterop.js new file mode 100644 index 0000000000000..8663c50643279 --- /dev/null +++ b/tests/baselines/reference/esbuildInterop.js @@ -0,0 +1,28 @@ +//// [tests/cases/conformance/module/esbuildInterop.ts] //// + +//// [package.json] +{ + "name": "dep", + "version": "1.0.0", + "main": "index.js" +} + +//// [index.d.ts] +declare const _default: string; +export default _default; + +//// [package.json] +{ + "type": "module" +} + +//// [index.ts] +import dep from "dep"; +dep.toLowerCase(); // Error +dep.default.toLowerCase(); // Ok + + +//// [index.js] +import dep from "dep"; +dep.toLowerCase(); // Error +dep.default.toLowerCase(); // Ok diff --git a/tests/baselines/reference/esbuildInterop.symbols b/tests/baselines/reference/esbuildInterop.symbols new file mode 100644 index 0000000000000..3760729565157 --- /dev/null +++ b/tests/baselines/reference/esbuildInterop.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/conformance/module/esbuildInterop.ts] //// + +=== /node_modules/dep/index.d.ts === +declare const _default: string; +>_default : Symbol(_default, Decl(index.d.ts, 0, 13)) + +export default _default; +>_default : Symbol(_default, Decl(index.d.ts, 0, 13)) + +=== /index.ts === +import dep from "dep"; +>dep : Symbol(dep, Decl(index.ts, 0, 6)) + +dep.toLowerCase(); // Error +>dep : Symbol(dep, Decl(index.ts, 0, 6)) + +dep.default.toLowerCase(); // Ok +>dep.default.toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --)) +>dep.default : Symbol(dep.default, Decl(index.d.ts, 0, 31)) +>dep : Symbol(dep, Decl(index.ts, 0, 6)) +>default : Symbol(dep.default, Decl(index.d.ts, 0, 31)) +>toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/esbuildInterop.types b/tests/baselines/reference/esbuildInterop.types new file mode 100644 index 0000000000000..392b87cfa0e22 --- /dev/null +++ b/tests/baselines/reference/esbuildInterop.types @@ -0,0 +1,27 @@ +//// [tests/cases/conformance/module/esbuildInterop.ts] //// + +=== /node_modules/dep/index.d.ts === +declare const _default: string; +>_default : string + +export default _default; +>_default : string + +=== /index.ts === +import dep from "dep"; +>dep : typeof dep + +dep.toLowerCase(); // Error +>dep.toLowerCase() : any +>dep.toLowerCase : any +>dep : typeof dep +>toLowerCase : any + +dep.default.toLowerCase(); // Ok +>dep.default.toLowerCase() : string +>dep.default.toLowerCase : () => string +>dep.default : string +>dep : typeof dep +>default : string +>toLowerCase : () => string + diff --git a/tests/cases/conformance/module/esbuildInterop.ts b/tests/cases/conformance/module/esbuildInterop.ts new file mode 100644 index 0000000000000..44b56fb62d173 --- /dev/null +++ b/tests/cases/conformance/module/esbuildInterop.ts @@ -0,0 +1,25 @@ +// @module: esnext +// @moduleResolution: bundler +// @moduleFormatDetection: bundler +// @moduleFormatInterop: bundlernode + +// @Filename: /node_modules/dep/package.json +{ + "name": "dep", + "version": "1.0.0", + "main": "index.js" +} + +// @Filename: /node_modules/dep/index.d.ts +declare const _default: string; +export default _default; + +// @Filename: /package.json +{ + "type": "module" +} + +// @Filename: /index.ts +import dep from "dep"; +dep.toLowerCase(); // Error +dep.default.toLowerCase(); // Ok From e764c32bd275b574541d23d46b0e4ddbd8afb646 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 9 Jan 2024 14:35:47 -0800 Subject: [PATCH 04/13] Set impliedNodeFormat when `moduleFormatInterop` is set --- src/compiler/checker.ts | 2 ++ src/compiler/program.ts | 15 ++++++--------- src/compiler/utilities.ts | 10 +++++++++- tests/cases/conformance/module/esbuildInterop.ts | 1 - 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f84813cbdf31c..877d171005bf9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -324,6 +324,7 @@ import { getMembersOfDeclaration, getModeForUsageLocation, getModifiers, + getModuleFormatInteropKind, getModuleInstanceState, getNameFromIndexInfo, getNameOfDeclaration, @@ -841,6 +842,7 @@ import { modifierToFlag, ModuleBlock, ModuleDeclaration, + ModuleFormatInteropKind, ModuleInstanceState, ModuleKind, ModuleResolutionKind, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 067b66dca5714..1317da273e558 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -286,6 +286,7 @@ import { ScriptTarget, setParent, setParentRecursive, + shouldComputeImpliedNodeFormat, shouldResolveJsRequire, skipTrivia, skipTypeChecking, @@ -1325,15 +1326,11 @@ export function getImpliedNodeFormatForFileWorker( host: ModuleResolutionHost, options: CompilerOptions, ) { - switch (getEmitModuleResolutionKind(options)) { - case ModuleResolutionKind.Node16: - case ModuleResolutionKind.NodeNext: - return fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Mjs]) ? ModuleKind.ESNext : - fileExtensionIsOneOf(fileName, [Extension.Dcts, Extension.Cts, Extension.Cjs]) ? ModuleKind.CommonJS : - fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx]) ? lookupFromPackageJson() : - undefined; // other extensions, like `json` or `tsbuildinfo`, are set as `undefined` here but they should never be fed through the transformer pipeline - default: - return undefined; + if (shouldComputeImpliedNodeFormat(options)) { + return fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Mjs]) ? ModuleKind.ESNext : + fileExtensionIsOneOf(fileName, [Extension.Dcts, Extension.Cts, Extension.Cjs]) ? ModuleKind.CommonJS : + fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx]) ? lookupFromPackageJson() : + undefined; // other extensions, like `json` or `tsbuildinfo`, are set as `undefined` here but they should never be fed through the transformer pipeline } function lookupFromPackageJson(): Partial { const state = getTemporaryModuleResolutionState(packageJsonInfoCache, host, options); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9fb9c1d6b6945..61373801cf5c0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -402,7 +402,6 @@ import { ModuleBlock, ModuleDeclaration, ModuleDetectionKind, - ModuleFormatDetectionKind, ModuleFormatInteropKind, ModuleKind, ModuleResolutionKind, @@ -8852,6 +8851,8 @@ export const getEmitModuleResolutionKind = computedOptions.moduleResolution.comp /** @internal */ export const getEmitModuleDetectionKind = computedOptions.moduleDetection.computeValue; /** @internal */ +export const getModuleFormatInteropKind = computedOptions.moduleFormatInterop.computeValue; +/** @internal */ export const getIsolatedModules = computedOptions.isolatedModules.computeValue; /** @internal */ export const getESModuleInterop = computedOptions.esModuleInterop.computeValue; @@ -8881,6 +8882,13 @@ export function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind) { return moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext; } +/** @internal */ +export function shouldComputeImpliedNodeFormat(compilerOptions: CompilerOptions) { + const moduleResolution = getEmitModuleResolutionKind(compilerOptions); + return ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext + || getModuleFormatInteropKind(compilerOptions) !== ModuleFormatInteropKind.Bundler; +} + /** @internal */ export function hasJsonModuleEmitEnabled(options: CompilerOptions) { switch (getEmitModuleKind(options)) { diff --git a/tests/cases/conformance/module/esbuildInterop.ts b/tests/cases/conformance/module/esbuildInterop.ts index 44b56fb62d173..72efb4762ff82 100644 --- a/tests/cases/conformance/module/esbuildInterop.ts +++ b/tests/cases/conformance/module/esbuildInterop.ts @@ -1,6 +1,5 @@ // @module: esnext // @moduleResolution: bundler -// @moduleFormatDetection: bundler // @moduleFormatInterop: bundlernode // @Filename: /node_modules/dep/package.json From 02ca29ab453435c236853dac79353733cd79ee0c Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 9 Jan 2024 15:42:57 -0800 Subject: [PATCH 05/13] Fix option name and commit baselines --- src/compiler/commandLineParser.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 7 +++++++ .../Default initialized TSConfig/tsconfig.json | 1 + .../Initialized TSConfig with --help/tsconfig.json | 1 + .../Initialized TSConfig with --watch/tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../Initialized TSConfig with files options/tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../moduleFormatInterop/tsconfig.json | 5 +++++ 14 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/config/showConfig/Shows tsconfig for single option/moduleFormatInterop/tsconfig.json diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 3aac4cd676729..bba9d93fa387c 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1158,7 +1158,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [ { name: "moduleFormatInterop", type: new Map(Object.entries({ - babel: ModuleFormatInteropKind.Bundler, + bundler: ModuleFormatInteropKind.Bundler, bundlernode: ModuleFormatInteropKind.BundlerNode, node16: ModuleFormatInteropKind.Node16, nodenext: ModuleFormatInteropKind.NodeNext, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c723fbebb0a16..ce70c9116e071 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -7539,6 +7539,7 @@ declare namespace ts { mapRoot?: string; maxNodeModuleJsDepth?: number; module?: ModuleKind; + moduleFormatInterop?: ModuleFormatInteropKind; moduleResolution?: ModuleResolutionKind; moduleSuffixes?: string[]; moduleDetection?: ModuleDetectionKind; @@ -7634,6 +7635,12 @@ declare namespace ts { Node16 = 100, NodeNext = 199, } + enum ModuleFormatInteropKind { + Bundler = 1, + BundlerNode = 2, + Node16 = 100, + NodeNext = 199, + } enum JsxEmit { None = 0, Preserve = 1, diff --git a/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json index e075f973c4d28..0dfefe4b86293 100644 --- a/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json index e075f973c4d28..0dfefe4b86293 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json index e075f973c4d28..0dfefe4b86293 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json index 3379ad1a3b576..cb38e5ff8c408 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index e9e873054b703..f722b04ac3c5c 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 178abdeca2791..5cee817ef5701 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json index 6136a0e0ce953..e663c4a27e2cd 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 84bdc4354ee70..5b951eee327b0 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index e075f973c4d28..0dfefe4b86293 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 8b051d2b3dd93..11981f94db0e5 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json index c0c664e0d7c8a..843ad06750bd0 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -39,6 +39,7 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/moduleFormatInterop/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/moduleFormatInterop/tsconfig.json new file mode 100644 index 0000000000000..f4972329728c4 --- /dev/null +++ b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/moduleFormatInterop/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "moduleFormatInterop": "bundler" + } +} From be466d528078b64482e3effdd308ccd88d602e6e Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 9 Jan 2024 16:13:44 -0800 Subject: [PATCH 06/13] Fix default import of ESM file with no default export --- src/compiler/checker.ts | 4 ++++ .../reference/importESMPackage.errors.txt | 20 ++++++++++++++++++ tests/baselines/reference/importESMPackage.js | 21 +++++++++++++++++++ .../reference/importESMPackage.symbols | 13 ++++++++++++ .../reference/importESMPackage.types | 15 +++++++++++++ .../conformance/module/importESMPackage.ts | 18 ++++++++++++++++ 6 files changed, 91 insertions(+) create mode 100644 tests/baselines/reference/importESMPackage.errors.txt create mode 100644 tests/baselines/reference/importESMPackage.js create mode 100644 tests/baselines/reference/importESMPackage.symbols create mode 100644 tests/baselines/reference/importESMPackage.types create mode 100644 tests/cases/conformance/module/importESMPackage.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 877d171005bf9..cbceb2f5ce0c5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4083,6 +4083,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // Declaration files (and ambient modules) if (!file || file.isDeclarationFile) { + // Unambiguously ESM files do not have a synthetic default + if (file?.impliedNodeFormat === ModuleKind.ESNext) { + return false; + } // Definitely cannot have a synthetic default if they have a syntactic default member specified const defaultExportSymbol = resolveExportByName(moduleSymbol, InternalSymbolName.Default, /*sourceNode*/ undefined, /*dontResolveAlias*/ true); // Dont resolve alias because we want the immediately exported symbol's declaration if (defaultExportSymbol && some(defaultExportSymbol.declarations, isSyntacticDefault)) { diff --git a/tests/baselines/reference/importESMPackage.errors.txt b/tests/baselines/reference/importESMPackage.errors.txt new file mode 100644 index 0000000000000..5c728770e55a2 --- /dev/null +++ b/tests/baselines/reference/importESMPackage.errors.txt @@ -0,0 +1,20 @@ +/index.ts(1,8): error TS1192: Module '"/node_modules/dep/index"' has no default export. + + +==== /node_modules/dep/package.json (0 errors) ==== + { + "name": "dep", + "version": "1.0.0", + "type": "module", + "main": "index.js" + } + +==== /node_modules/dep/index.d.ts (0 errors) ==== + export declare const foo: string; + +==== /index.ts (1 errors) ==== + import dep from "dep"; // Error + ~~~ +!!! error TS1192: Module '"/node_modules/dep/index"' has no default export. + dep.foo; + \ No newline at end of file diff --git a/tests/baselines/reference/importESMPackage.js b/tests/baselines/reference/importESMPackage.js new file mode 100644 index 0000000000000..3b27d5bc0055b --- /dev/null +++ b/tests/baselines/reference/importESMPackage.js @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/module/importESMPackage.ts] //// + +//// [package.json] +{ + "name": "dep", + "version": "1.0.0", + "type": "module", + "main": "index.js" +} + +//// [index.d.ts] +export declare const foo: string; + +//// [index.ts] +import dep from "dep"; // Error +dep.foo; + + +//// [index.js] +import dep from "dep"; // Error +dep.foo; diff --git a/tests/baselines/reference/importESMPackage.symbols b/tests/baselines/reference/importESMPackage.symbols new file mode 100644 index 0000000000000..6f983567b5e7f --- /dev/null +++ b/tests/baselines/reference/importESMPackage.symbols @@ -0,0 +1,13 @@ +//// [tests/cases/conformance/module/importESMPackage.ts] //// + +=== /node_modules/dep/index.d.ts === +export declare const foo: string; +>foo : Symbol(foo, Decl(index.d.ts, 0, 20)) + +=== /index.ts === +import dep from "dep"; // Error +>dep : Symbol(dep, Decl(index.ts, 0, 6)) + +dep.foo; +>dep : Symbol(dep, Decl(index.ts, 0, 6)) + diff --git a/tests/baselines/reference/importESMPackage.types b/tests/baselines/reference/importESMPackage.types new file mode 100644 index 0000000000000..f24be278f72c5 --- /dev/null +++ b/tests/baselines/reference/importESMPackage.types @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/module/importESMPackage.ts] //// + +=== /node_modules/dep/index.d.ts === +export declare const foo: string; +>foo : string + +=== /index.ts === +import dep from "dep"; // Error +>dep : any + +dep.foo; +>dep.foo : any +>dep : any +>foo : any + diff --git a/tests/cases/conformance/module/importESMPackage.ts b/tests/cases/conformance/module/importESMPackage.ts new file mode 100644 index 0000000000000..f18d93dad8c55 --- /dev/null +++ b/tests/cases/conformance/module/importESMPackage.ts @@ -0,0 +1,18 @@ +// @module: esnext +// @moduleResolution: bundler +// @moduleFormatInterop: bundlernode + +// @Filename: /node_modules/dep/package.json +{ + "name": "dep", + "version": "1.0.0", + "type": "module", + "main": "index.js" +} + +// @Filename: /node_modules/dep/index.d.ts +export declare const foo: string; + +// @Filename: /index.ts +import dep from "dep"; // Error +dep.foo; From 4276a364e9aeaf97f40ab1526edb6e1dfd856116 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 7 May 2024 15:27:35 -0700 Subject: [PATCH 07/13] Remove unused function --- src/compiler/utilities.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2b9ce7a1c5e0d..b9c53eff71f28 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -9076,13 +9076,6 @@ export function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind) { return moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext; } -/** @internal */ -export function shouldComputeImpliedNodeFormat(compilerOptions: CompilerOptions) { - const moduleResolution = getEmitModuleResolutionKind(compilerOptions); - return ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext - || getModuleFormatInteropKind(compilerOptions) !== ModuleFormatInteropKind.Bundler; -} - /** @internal */ export function hasJsonModuleEmitEnabled(options: CompilerOptions) { switch (getEmitModuleKind(options)) { From 961857627396b5fa6e0791b02467b4c8d08c1b8e Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 7 May 2024 15:32:33 -0700 Subject: [PATCH 08/13] Update to use new impliedNodeFormat host method --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f0a5cd3fd9aec..4425c89f5aa38 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3651,7 +3651,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Declaration files (and ambient modules) if (!file || file.isDeclarationFile) { // Unambiguously ESM files do not have a synthetic default - if (file?.impliedNodeFormat === ModuleKind.ESNext) { + if (file && host.getImpliedNodeFormatForEmit(file) === ModuleKind.ESNext) { return false; } // Definitely cannot have a synthetic default if they have a syntactic default member specified From d5177c5a6ec8edc76e6d63413c5681ec1b2fec6c Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 8 May 2024 09:54:44 -0700 Subject: [PATCH 09/13] Remove unrelated test --- .../reference/importESMPackage.errors.txt | 20 ------------------ tests/baselines/reference/importESMPackage.js | 21 ------------------- .../reference/importESMPackage.symbols | 13 ------------ .../reference/importESMPackage.types | 15 ------------- .../conformance/module/importESMPackage.ts | 18 ---------------- 5 files changed, 87 deletions(-) delete mode 100644 tests/baselines/reference/importESMPackage.errors.txt delete mode 100644 tests/baselines/reference/importESMPackage.js delete mode 100644 tests/baselines/reference/importESMPackage.symbols delete mode 100644 tests/baselines/reference/importESMPackage.types delete mode 100644 tests/cases/conformance/module/importESMPackage.ts diff --git a/tests/baselines/reference/importESMPackage.errors.txt b/tests/baselines/reference/importESMPackage.errors.txt deleted file mode 100644 index 5c728770e55a2..0000000000000 --- a/tests/baselines/reference/importESMPackage.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -/index.ts(1,8): error TS1192: Module '"/node_modules/dep/index"' has no default export. - - -==== /node_modules/dep/package.json (0 errors) ==== - { - "name": "dep", - "version": "1.0.0", - "type": "module", - "main": "index.js" - } - -==== /node_modules/dep/index.d.ts (0 errors) ==== - export declare const foo: string; - -==== /index.ts (1 errors) ==== - import dep from "dep"; // Error - ~~~ -!!! error TS1192: Module '"/node_modules/dep/index"' has no default export. - dep.foo; - \ No newline at end of file diff --git a/tests/baselines/reference/importESMPackage.js b/tests/baselines/reference/importESMPackage.js deleted file mode 100644 index 3b27d5bc0055b..0000000000000 --- a/tests/baselines/reference/importESMPackage.js +++ /dev/null @@ -1,21 +0,0 @@ -//// [tests/cases/conformance/module/importESMPackage.ts] //// - -//// [package.json] -{ - "name": "dep", - "version": "1.0.0", - "type": "module", - "main": "index.js" -} - -//// [index.d.ts] -export declare const foo: string; - -//// [index.ts] -import dep from "dep"; // Error -dep.foo; - - -//// [index.js] -import dep from "dep"; // Error -dep.foo; diff --git a/tests/baselines/reference/importESMPackage.symbols b/tests/baselines/reference/importESMPackage.symbols deleted file mode 100644 index 6f983567b5e7f..0000000000000 --- a/tests/baselines/reference/importESMPackage.symbols +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/conformance/module/importESMPackage.ts] //// - -=== /node_modules/dep/index.d.ts === -export declare const foo: string; ->foo : Symbol(foo, Decl(index.d.ts, 0, 20)) - -=== /index.ts === -import dep from "dep"; // Error ->dep : Symbol(dep, Decl(index.ts, 0, 6)) - -dep.foo; ->dep : Symbol(dep, Decl(index.ts, 0, 6)) - diff --git a/tests/baselines/reference/importESMPackage.types b/tests/baselines/reference/importESMPackage.types deleted file mode 100644 index f24be278f72c5..0000000000000 --- a/tests/baselines/reference/importESMPackage.types +++ /dev/null @@ -1,15 +0,0 @@ -//// [tests/cases/conformance/module/importESMPackage.ts] //// - -=== /node_modules/dep/index.d.ts === -export declare const foo: string; ->foo : string - -=== /index.ts === -import dep from "dep"; // Error ->dep : any - -dep.foo; ->dep.foo : any ->dep : any ->foo : any - diff --git a/tests/cases/conformance/module/importESMPackage.ts b/tests/cases/conformance/module/importESMPackage.ts deleted file mode 100644 index f18d93dad8c55..0000000000000 --- a/tests/cases/conformance/module/importESMPackage.ts +++ /dev/null @@ -1,18 +0,0 @@ -// @module: esnext -// @moduleResolution: bundler -// @moduleFormatInterop: bundlernode - -// @Filename: /node_modules/dep/package.json -{ - "name": "dep", - "version": "1.0.0", - "type": "module", - "main": "index.js" -} - -// @Filename: /node_modules/dep/index.d.ts -export declare const foo: string; - -// @Filename: /index.ts -import dep from "dep"; // Error -dep.foo; From aebc53c57c5c8ce69886ae586a68a0b3c82d0b78 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 8 May 2024 10:11:34 -0700 Subject: [PATCH 10/13] Check option to determine synthetic default --- src/compiler/checker.ts | 7 +++-- src/testRunner/compilerRunner.ts | 1 + ...op(moduleformatinterop=bundler).errors.txt | 26 +++++++++++++++++++ ...oduleformatinterop=bundlernode).errors.txt | 26 +++++++++++++++++++ .../conformance/module/esbuildInterop.ts | 8 +++--- 5 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/esbuildInterop(moduleformatinterop=bundler).errors.txt create mode 100644 tests/baselines/reference/esbuildInterop(moduleformatinterop=bundlernode).errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4425c89f5aa38..61772fde2c7c8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3635,7 +3635,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const usageMode = file && getEmitSyntaxForModuleSpecifierExpression(usage); if (file && usageMode !== undefined) { const targetMode = host.getImpliedNodeFormatForEmit(file); - if (usageMode === ModuleKind.ESNext && targetMode === ModuleKind.CommonJS && ModuleKind.Node16 <= moduleKind && moduleKind <= ModuleKind.NodeNext) { + const moduleFormatInterop = getModuleFormatInteropKind(compilerOptions); + const usesNodeLikeInteropRules = moduleFormatInterop === ModuleFormatInteropKind.BundlerNode + || ModuleFormatInteropKind.Node16 <= moduleFormatInterop && moduleFormatInterop <= ModuleFormatInteropKind.NodeNext; + if (usageMode === ModuleKind.ESNext && targetMode !== ModuleKind.ESNext && usesNodeLikeInteropRules) { // In Node.js, CommonJS modules always have a synthetic default when imported into ESM return true; } @@ -4613,7 +4616,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) { errorOnImplicitAnyModule(/*isError*/ false, errorNode, currentSourceFile, mode, resolvedModule, moduleReference); } - if (moduleFormatInterop === ModuleFormatInteropKind.Node16 || moduleFormatInterop === ModuleFormatInteropKind.NodeNext) { + if (ModuleFormatInteropKind.Node16 <= moduleFormatInterop && moduleFormatInterop <= ModuleFormatInteropKind.NodeNext) { const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration); const overrideHost = findAncestor(location, l => isImportTypeNode(l) || isExportDeclaration(l) || isImportDeclaration(l)) as ImportTypeNode | ImportDeclaration | ExportDeclaration | undefined; // An override clause will take effect for type-only imports and import types, and allows importing the types across formats, regardless of diff --git a/src/testRunner/compilerRunner.ts b/src/testRunner/compilerRunner.ts index 93bc55c1159fe..491d4aaa31828 100644 --- a/src/testRunner/compilerRunner.ts +++ b/src/testRunner/compilerRunner.ts @@ -142,6 +142,7 @@ class CompilerTest { "jsx", "module", "moduleDetection", + "moduleFormatInterop", "moduleResolution", "noEmit", "noImplicitAny", diff --git a/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundler).errors.txt b/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundler).errors.txt new file mode 100644 index 0000000000000..981e8790b6dc8 --- /dev/null +++ b/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundler).errors.txt @@ -0,0 +1,26 @@ +/index.ts(3,5): error TS2339: Property 'default' does not exist on type 'string'. + + +==== /node_modules/dep/package.json (0 errors) ==== + { + "name": "dep", + "version": "1.0.0", + "main": "index.js" + } + +==== /node_modules/dep/index.d.ts (0 errors) ==== + declare const _default: string; + export default _default; + +==== /package.json (0 errors) ==== + { + "type": "module" + } + +==== /index.ts (1 errors) ==== + import dep from "dep"; + dep.toLowerCase(); // Error in bundlernode + dep.default.toLowerCase(); // Error in bundler + ~~~~~~~ +!!! error TS2339: Property 'default' does not exist on type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundlernode).errors.txt b/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundlernode).errors.txt new file mode 100644 index 0000000000000..7c25932f39bf8 --- /dev/null +++ b/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundlernode).errors.txt @@ -0,0 +1,26 @@ +/index.ts(2,5): error TS2339: Property 'toLowerCase' does not exist on type 'typeof import("/node_modules/dep/index")'. + + +==== /node_modules/dep/package.json (0 errors) ==== + { + "name": "dep", + "version": "1.0.0", + "main": "index.js" + } + +==== /node_modules/dep/index.d.ts (0 errors) ==== + declare const _default: string; + export default _default; + +==== /package.json (0 errors) ==== + { + "type": "module" + } + +==== /index.ts (1 errors) ==== + import dep from "dep"; + dep.toLowerCase(); // Error in bundlernode + ~~~~~~~~~~~ +!!! error TS2339: Property 'toLowerCase' does not exist on type 'typeof import("/node_modules/dep/index")'. + dep.default.toLowerCase(); // Error in bundler + \ No newline at end of file diff --git a/tests/cases/conformance/module/esbuildInterop.ts b/tests/cases/conformance/module/esbuildInterop.ts index 72efb4762ff82..751664a66e75a 100644 --- a/tests/cases/conformance/module/esbuildInterop.ts +++ b/tests/cases/conformance/module/esbuildInterop.ts @@ -1,6 +1,8 @@ // @module: esnext // @moduleResolution: bundler -// @moduleFormatInterop: bundlernode +// @moduleFormatInterop: bundler, bundlernode +// @noEmit: true +// @noTypesAndSymbols: true // @Filename: /node_modules/dep/package.json { @@ -20,5 +22,5 @@ export default _default; // @Filename: /index.ts import dep from "dep"; -dep.toLowerCase(); // Error -dep.default.toLowerCase(); // Ok +dep.toLowerCase(); // Error in bundlernode +dep.default.toLowerCase(); // Error in bundler From d49899e8dc93edd913ff56d4b29a16bc371653c7 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 9 May 2024 11:17:38 -0700 Subject: [PATCH 11/13] Add affectsSemanticDiagnostics --- src/compiler/commandLineParser.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 98a9131c85aaa..5934ecd1edaa0 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1205,6 +1205,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [ node16: ModuleFormatInteropKind.Node16, nodenext: ModuleFormatInteropKind.NodeNext, })), + affectsSemanticDiagnostics: true, category: Diagnostics.Modules, description: Diagnostics.Specify_the_target_runtime_s_rules_for_ESM_CommonJS_interoperation, defaultValueDescription: Diagnostics.node16_when_module_is_node16_nodenext_when_module_is_nodenext_bundler_otherwise, From 5ffc92b5f5f59a0846506db66e720e4720a20b31 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 13 May 2024 12:22:32 -0700 Subject: [PATCH 12/13] Split `moduleFormatInterop` into `defaultIsModuleExports` and `allowRequireESM` --- src/compiler/checker.ts | 21 ++++++----- src/compiler/commandLineParser.ts | 31 ++++++++++++---- src/compiler/diagnosticMessages.json | 12 +++++- src/compiler/types.ts | 14 +++++-- src/compiler/utilities.ts | 37 ++++++++++++------- src/testRunner/compilerRunner.ts | 3 +- tests/baselines/reference/api/typescript.d.ts | 14 +++++-- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../allowRequireESM/tsconfig.json | 5 +++ .../defaultIsModuleExports/tsconfig.json | 5 +++ ...p(defaultismoduleexports=auto).errors.txt} | 4 +- ...faultismoduleexports=nodenext).errors.txt} | 4 +- ...oduleformatinterop=bundlernode).errors.txt | 26 ------------- tests/baselines/reference/esbuildInterop.js | 28 -------------- .../reference/esbuildInterop.symbols | 23 ------------ .../baselines/reference/esbuildInterop.types | 27 -------------- ...Interop(allowrequireesm=node16).errors.txt | 21 +++++++++++ .../conformance/module/esbuildInterop.ts | 6 +-- .../conformance/module/webpackInterop.ts | 21 +++++++++++ 29 files changed, 172 insertions(+), 163 deletions(-) create mode 100644 tests/baselines/reference/config/showConfig/Shows tsconfig for single option/allowRequireESM/tsconfig.json create mode 100644 tests/baselines/reference/config/showConfig/Shows tsconfig for single option/defaultIsModuleExports/tsconfig.json rename tests/baselines/reference/{esbuildInterop(moduleformatinterop=bundler).errors.txt => esbuildInterop(defaultismoduleexports=auto).errors.txt} (82%) rename tests/baselines/reference/{esbuildInterop.errors.txt => esbuildInterop(defaultismoduleexports=nodenext).errors.txt} (84%) delete mode 100644 tests/baselines/reference/esbuildInterop(moduleformatinterop=bundlernode).errors.txt delete mode 100644 tests/baselines/reference/esbuildInterop.js delete mode 100644 tests/baselines/reference/esbuildInterop.symbols delete mode 100644 tests/baselines/reference/esbuildInterop.types create mode 100644 tests/baselines/reference/webpackInterop(allowrequireesm=node16).errors.txt create mode 100644 tests/cases/conformance/module/webpackInterop.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 019079a2f312e..c66b079df1cf1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8,6 +8,7 @@ import { addSyntheticLeadingComment, AliasDeclarationNode, AllAccessorDeclarations, + AllowRequireESM, AmbientModuleDeclaration, and, AnonymousType, @@ -138,6 +139,7 @@ import { Decorator, deduplicate, DefaultClause, + DefaultIsModuleExports, defaultMaximumTruncationLength, DeferredTypeReference, DeleteExpression, @@ -245,6 +247,7 @@ import { GetAccessorDeclaration, getAliasDeclarationFromName, getAllJSDocTags, + getAllowRequireESM, getAllowSyntheticDefaultImports, getAncestor, getAssignedExpandoInitializer, @@ -268,6 +271,7 @@ import { getDeclarationsOfKind, getDeclaredExpandoInitializer, getDecorators, + getDefaultIsModuleExports, getDirectoryPath, getEffectiveBaseTypeNode, getEffectiveConstraintOfTypeParameter, @@ -332,7 +336,6 @@ import { getLineAndCharacterOfPosition, getMembersOfDeclaration, getModifiers, - getModuleFormatInteropKind, getModuleInstanceState, getNameFromImportAttribute, getNameFromIndexInfo, @@ -860,7 +863,6 @@ import { modifierToFlag, ModuleBlock, ModuleDeclaration, - ModuleFormatInteropKind, ModuleInstanceState, ModuleKind, ModuleResolutionKind, @@ -3636,9 +3638,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const usageMode = file && getEmitSyntaxForModuleSpecifierExpression(usage); if (file && usageMode !== undefined) { const targetMode = host.getImpliedNodeFormatForEmit(file); - const moduleFormatInterop = getModuleFormatInteropKind(compilerOptions); - const usesNodeLikeInteropRules = moduleFormatInterop === ModuleFormatInteropKind.BundlerNode - || ModuleFormatInteropKind.Node16 <= moduleFormatInterop && moduleFormatInterop <= ModuleFormatInteropKind.NodeNext; + const defaultIsModuleExports = getDefaultIsModuleExports(compilerOptions); + const usesNodeLikeInteropRules = DefaultIsModuleExports.Node16 <= defaultIsModuleExports && defaultIsModuleExports <= DefaultIsModuleExports.NodeNext; if (usageMode === ModuleKind.ESNext && targetMode !== ModuleKind.ESNext && usesNodeLikeInteropRules) { // In Node.js, CommonJS modules always have a synthetic default when imported into ESM return true; @@ -4580,8 +4581,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const mode = contextSpecifier && isStringLiteralLike(contextSpecifier) ? host.getModeForUsageLocation(currentSourceFile, contextSpecifier) : host.getDefaultResolutionModeForFile(currentSourceFile); + const importingFileIsJavaScript = isSourceFileJS(currentSourceFile); const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); - const moduleFormatInterop = getModuleFormatInteropKind(compilerOptions); + const allowRequireESM = getAllowRequireESM(compilerOptions); const resolvedModule = host.getResolvedModule(currentSourceFile, moduleReference, mode)?.resolvedModule; const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule, currentSourceFile); const sourceFile = resolvedModule @@ -4617,12 +4619,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) { errorOnImplicitAnyModule(/*isError*/ false, errorNode, currentSourceFile, mode, resolvedModule, moduleReference); } - if (ModuleFormatInteropKind.Node16 <= moduleFormatInterop && moduleFormatInterop <= ModuleFormatInteropKind.NodeNext) { - const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration); + if (AllowRequireESM.Node16 <= allowRequireESM && allowRequireESM <= AllowRequireESM.NodeNext) { + const isSyncImport = (host.getImpliedNodeFormatForEmit(currentSourceFile) === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) + || !!findAncestor(location, n => isImportEqualsDeclaration(n) || importingFileIsJavaScript && isVariableDeclarationInitializedToBareOrAccessedRequire(n)); const overrideHost = findAncestor(location, l => isImportTypeNode(l) || isExportDeclaration(l) || isImportDeclaration(l)) as ImportTypeNode | ImportDeclaration | ExportDeclaration | undefined; // An override clause will take effect for type-only imports and import types, and allows importing the types across formats, regardless of // normal mode restrictions - if (isSyncImport && sourceFile.impliedNodeFormat === ModuleKind.ESNext && !hasResolutionModeOverride(overrideHost)) { + if (isSyncImport && host.getImpliedNodeFormatForEmit(sourceFile) === ModuleKind.ESNext && !hasResolutionModeOverride(overrideHost)) { if (findAncestor(location, isImportEqualsDeclaration)) { // ImportEquals in a ESM file resolving to another ESM file error(errorNode, Diagnostics.Module_0_cannot_be_imported_using_this_construct_The_specifier_only_resolves_to_an_ES_module_which_cannot_be_imported_with_require_Use_an_ECMAScript_import_instead, moduleReference); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 5934ecd1edaa0..7e9002ffcb739 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1,4 +1,5 @@ import { + AllowRequireESM, AlternateModeDiagnostics, append, arrayFrom, @@ -23,6 +24,7 @@ import { createDiagnosticForNodeInSourceFile, createGetCanonicalFileName, Debug, + DefaultIsModuleExports, Diagnostic, DiagnosticArguments, DiagnosticMessage, @@ -83,7 +85,6 @@ import { mapIterator, MapLike, ModuleDetectionKind, - ModuleFormatInteropKind, ModuleKind, ModuleResolutionKind, NewLineKind, @@ -1198,17 +1199,31 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [ description: Diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports, }, { - name: "moduleFormatInterop", + name: "defaultIsModuleExports", type: new Map(Object.entries({ - bundler: ModuleFormatInteropKind.Bundler, - bundlernode: ModuleFormatInteropKind.BundlerNode, - node16: ModuleFormatInteropKind.Node16, - nodenext: ModuleFormatInteropKind.NodeNext, + auto: DefaultIsModuleExports.Auto, + node16: DefaultIsModuleExports.Node16, + nodenext: DefaultIsModuleExports.NodeNext, })), affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: Diagnostics.Modules, + description: Diagnostics.Specify_the_target_runtime_s_rules_for_default_imports_targeting_CommonJS_modules, + defaultValueDescription: Diagnostics.node16_when_module_is_node16_nodenext_when_module_is_nodenext_auto_otherwise, + }, + { + name: "allowRequireESM", + type: new Map(Object.entries({ + never: AllowRequireESM.Never, + always: AllowRequireESM.Always, + node16: AllowRequireESM.Node16, + nodenext: AllowRequireESM.NodeNext, + })), + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, category: Diagnostics.Modules, - description: Diagnostics.Specify_the_target_runtime_s_rules_for_ESM_CommonJS_interoperation, - defaultValueDescription: Diagnostics.node16_when_module_is_node16_nodenext_when_module_is_nodenext_bundler_otherwise, + description: Diagnostics.Specify_the_target_runtime_s_rules_for_CommonJS_require_calls_targeting_ECMAScript_modules, + defaultValueDescription: Diagnostics.node16_when_module_is_node16_nodenext_when_module_is_nodenext_always_otherwise, }, // Source Maps diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d92d7d7d2ec0d..ed0097d151b2a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -6392,10 +6392,14 @@ "category": "Message", "code": 6805 }, - "Specify the target runtime's rules for ESM-CommonJS interoperation.": { + "Specify the target runtime's rules for default imports targeting CommonJS modules.": { "category": "Message", "code": 6806 }, + "Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules.": { + "category": "Message", + "code": 6807 + }, "one of:": { "category": "Message", @@ -6525,10 +6529,14 @@ "category": "Error", "code": 6931 }, - "'node16' when 'module' is 'node16'; 'nodenext' when 'module' is 'nodenext'; 'bundler' otherwise.": { + "'node16' when 'module' is 'node16'; 'nodenext' when 'module' is 'nodenext'; 'auto' otherwise.": { "category": "Message", "code": 6932 }, + "'node16' when 'module' is 'node16'; 'nodenext' when 'module' is 'nodenext'; 'always' otherwise.": { + "category": "Message", + "code": 6933 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9ae921aab7d54..c3b4d37532eac 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -7227,6 +7227,7 @@ export interface CompilerOptions { allowJs?: boolean; /** @internal */ allowNonTsExtensions?: boolean; allowArbitraryExtensions?: boolean; + allowRequireESM?: AllowRequireESM; allowSyntheticDefaultImports?: boolean; allowUmdGlobalAccess?: boolean; allowUnreachableCode?: boolean; @@ -7254,6 +7255,7 @@ export interface CompilerOptions { declarationMap?: boolean; emitDeclarationOnly?: boolean; declarationDir?: string; + defaultIsModuleExports?: DefaultIsModuleExports; /** @internal */ diagnostics?: boolean; /** @internal */ extendedDiagnostics?: boolean; disableSizeLimit?: boolean; @@ -7290,7 +7292,6 @@ export interface CompilerOptions { mapRoot?: string; maxNodeModuleJsDepth?: number; module?: ModuleKind; - moduleFormatInterop?: ModuleFormatInteropKind; moduleResolution?: ModuleResolutionKind; moduleSuffixes?: string[]; moduleDetection?: ModuleDetectionKind; @@ -7424,10 +7425,15 @@ export enum ModuleKind { Preserve = 200, } -export enum ModuleFormatInteropKind { - Bundler = 1, - BundlerNode = 2, +export enum DefaultIsModuleExports { + Auto = 1, + Node16 = 100, + NodeNext = 199, +} +export enum AllowRequireESM { + Never = 0, + Always = 1, Node16 = 100, NodeNext = 199, } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b9c53eff71f28..4dd758ca57c3d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -6,6 +6,7 @@ import { affectsDeclarationPathOptionDeclarations, affectsEmitOptionDeclarations, AllAccessorDeclarations, + AllowRequireESM, AmbientModuleDeclaration, AmpersandAmpersandEqualsToken, AnyImportOrBareOrAccessedRequire, @@ -90,6 +91,7 @@ import { DeclarationWithTypeParameters, Decorator, DefaultClause, + DefaultIsModuleExports, DestructuringAssignment, Diagnostic, DiagnosticArguments, @@ -420,7 +422,6 @@ import { ModuleBlock, ModuleDeclaration, ModuleDetectionKind, - ModuleFormatInteropKind, ModuleKind, ModuleResolutionKind, moduleResolutionOptionDeclarations, @@ -8853,20 +8854,28 @@ export const computedOptions = createComputedCompilerOptions({ computedOptions.module.computeValue(compilerOptions) === ModuleKind.NodeNext ? ModuleDetectionKind.Force : ModuleDetectionKind.Auto); }, }, - moduleFormatInterop: { + defaultIsModuleExports: { dependencies: ["module", "target"], - computeValue: (compilerOptions): ModuleFormatInteropKind => { - if (compilerOptions.moduleFormatInterop !== undefined) { - return compilerOptions.moduleFormatInterop; + computeValue: (compilerOptions): DefaultIsModuleExports => { + if (compilerOptions.defaultIsModuleExports !== undefined) { + return compilerOptions.defaultIsModuleExports; } - switch (computedOptions.module.computeValue(compilerOptions)) { - case ModuleKind.Node16: - return ModuleFormatInteropKind.Node16; - case ModuleKind.NodeNext: - return ModuleFormatInteropKind.NodeNext; - default: - return ModuleFormatInteropKind.Bundler; + const moduleKind = computedOptions.module.computeValue(compilerOptions); + return moduleKind === ModuleKind.Node16 ? DefaultIsModuleExports.Node16 : + moduleKind === ModuleKind.NodeNext ? DefaultIsModuleExports.NodeNext : + DefaultIsModuleExports.Auto; + }, + }, + allowRequireESM: { + dependencies: ["module", "target"], + computeValue: (compilerOptions): AllowRequireESM => { + if (compilerOptions.allowRequireESM !== undefined) { + return compilerOptions.allowRequireESM; } + const moduleKind = computedOptions.module.computeValue(compilerOptions); + return moduleKind === ModuleKind.Node16 ? AllowRequireESM.Node16 : + moduleKind === ModuleKind.NodeNext ? AllowRequireESM.NodeNext : + AllowRequireESM.Always; }, }, isolatedModules: { @@ -9045,7 +9054,9 @@ export const getEmitModuleResolutionKind = computedOptions.moduleResolution.comp /** @internal */ export const getEmitModuleDetectionKind = computedOptions.moduleDetection.computeValue; /** @internal */ -export const getModuleFormatInteropKind = computedOptions.moduleFormatInterop.computeValue; +export const getDefaultIsModuleExports = computedOptions.defaultIsModuleExports.computeValue; +/** @internal */ +export const getAllowRequireESM = computedOptions.allowRequireESM.computeValue; /** @internal */ export const getIsolatedModules = computedOptions.isolatedModules.computeValue; /** @internal */ diff --git a/src/testRunner/compilerRunner.ts b/src/testRunner/compilerRunner.ts index 491d4aaa31828..18c9eb679db96 100644 --- a/src/testRunner/compilerRunner.ts +++ b/src/testRunner/compilerRunner.ts @@ -129,8 +129,10 @@ class CompilerTest { private static varyBy: readonly string[] = [ "allowArbitraryExtensions", "allowImportingTsExtensions", + "allowRequireESM", "allowSyntheticDefaultImports", "alwaysStrict", + "defaultIsModuleExports", "downlevelIteration", "experimentalDecorators", "emitDecoratorMetadata", @@ -142,7 +144,6 @@ class CompilerTest { "jsx", "module", "moduleDetection", - "moduleFormatInterop", "moduleResolution", "noEmit", "noImplicitAny", diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 51da08c2b5b92..f266a29a4b305 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -6902,6 +6902,7 @@ declare namespace ts { allowImportingTsExtensions?: boolean; allowJs?: boolean; allowArbitraryExtensions?: boolean; + allowRequireESM?: AllowRequireESM; allowSyntheticDefaultImports?: boolean; allowUmdGlobalAccess?: boolean; allowUnreachableCode?: boolean; @@ -6916,6 +6917,7 @@ declare namespace ts { declarationMap?: boolean; emitDeclarationOnly?: boolean; declarationDir?: string; + defaultIsModuleExports?: DefaultIsModuleExports; disableSizeLimit?: boolean; disableSourceOfProjectReferenceRedirect?: boolean; disableSolutionSearching?: boolean; @@ -6942,7 +6944,6 @@ declare namespace ts { mapRoot?: string; maxNodeModuleJsDepth?: number; module?: ModuleKind; - moduleFormatInterop?: ModuleFormatInteropKind; moduleResolution?: ModuleResolutionKind; moduleSuffixes?: string[]; moduleDetection?: ModuleDetectionKind; @@ -7045,9 +7046,14 @@ declare namespace ts { NodeNext = 199, Preserve = 200, } - enum ModuleFormatInteropKind { - Bundler = 1, - BundlerNode = 2, + enum DefaultIsModuleExports { + Auto = 1, + Node16 = 100, + NodeNext = 199, + } + enum AllowRequireESM { + Never = 0, + Always = 1, Node16 = 100, NodeNext = 199, } diff --git a/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json index 5a56795a3ae2a..5f4490bb821c6 100644 --- a/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json index 5a56795a3ae2a..5f4490bb821c6 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json index 5a56795a3ae2a..5f4490bb821c6 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json index b6658b53e2557..a7081180b6039 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index e2e05e893aa2b..40e046ed10df5 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index a65503ad8635b..f87bb3feb24db 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json index 71ec6feaece2b..1bb17f3d0728d 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index a98705ca32b88..4a3e4fa8a8b14 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 5a56795a3ae2a..5f4490bb821c6 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index a2707a9da3733..302fe7dd4b7df 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json index 032982d928e31..9f582764d85d1 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -39,7 +39,8 @@ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "moduleFormatInterop": "bundler", /* Specify the target runtime's rules for ESM-CommonJS interoperation. */ + // "defaultIsModuleExports": "auto", /* Specify the target runtime's rules for default imports targeting CommonJS modules. */ + // "allowRequireESM": "never", /* Specify the target runtime's rules for CommonJS 'require' calls targeting ECMAScript modules. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ diff --git a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/allowRequireESM/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/allowRequireESM/tsconfig.json new file mode 100644 index 0000000000000..47369742b654f --- /dev/null +++ b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/allowRequireESM/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "allowRequireESM": "never" + } +} diff --git a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/defaultIsModuleExports/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/defaultIsModuleExports/tsconfig.json new file mode 100644 index 0000000000000..313c3e7950b09 --- /dev/null +++ b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/defaultIsModuleExports/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "defaultIsModuleExports": "auto" + } +} diff --git a/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundler).errors.txt b/tests/baselines/reference/esbuildInterop(defaultismoduleexports=auto).errors.txt similarity index 82% rename from tests/baselines/reference/esbuildInterop(moduleformatinterop=bundler).errors.txt rename to tests/baselines/reference/esbuildInterop(defaultismoduleexports=auto).errors.txt index 981e8790b6dc8..b5bc74655743c 100644 --- a/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundler).errors.txt +++ b/tests/baselines/reference/esbuildInterop(defaultismoduleexports=auto).errors.txt @@ -19,8 +19,8 @@ ==== /index.ts (1 errors) ==== import dep from "dep"; - dep.toLowerCase(); // Error in bundlernode - dep.default.toLowerCase(); // Error in bundler + dep.toLowerCase(); // Error in nodenext + dep.default.toLowerCase(); // Error in auto ~~~~~~~ !!! error TS2339: Property 'default' does not exist on type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/esbuildInterop.errors.txt b/tests/baselines/reference/esbuildInterop(defaultismoduleexports=nodenext).errors.txt similarity index 84% rename from tests/baselines/reference/esbuildInterop.errors.txt rename to tests/baselines/reference/esbuildInterop(defaultismoduleexports=nodenext).errors.txt index 8f8d5f72ad359..ee0d91b41e490 100644 --- a/tests/baselines/reference/esbuildInterop.errors.txt +++ b/tests/baselines/reference/esbuildInterop(defaultismoduleexports=nodenext).errors.txt @@ -19,8 +19,8 @@ ==== /index.ts (1 errors) ==== import dep from "dep"; - dep.toLowerCase(); // Error + dep.toLowerCase(); // Error in nodenext ~~~~~~~~~~~ !!! error TS2339: Property 'toLowerCase' does not exist on type 'typeof import("/node_modules/dep/index")'. - dep.default.toLowerCase(); // Ok + dep.default.toLowerCase(); // Error in auto \ No newline at end of file diff --git a/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundlernode).errors.txt b/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundlernode).errors.txt deleted file mode 100644 index 7c25932f39bf8..0000000000000 --- a/tests/baselines/reference/esbuildInterop(moduleformatinterop=bundlernode).errors.txt +++ /dev/null @@ -1,26 +0,0 @@ -/index.ts(2,5): error TS2339: Property 'toLowerCase' does not exist on type 'typeof import("/node_modules/dep/index")'. - - -==== /node_modules/dep/package.json (0 errors) ==== - { - "name": "dep", - "version": "1.0.0", - "main": "index.js" - } - -==== /node_modules/dep/index.d.ts (0 errors) ==== - declare const _default: string; - export default _default; - -==== /package.json (0 errors) ==== - { - "type": "module" - } - -==== /index.ts (1 errors) ==== - import dep from "dep"; - dep.toLowerCase(); // Error in bundlernode - ~~~~~~~~~~~ -!!! error TS2339: Property 'toLowerCase' does not exist on type 'typeof import("/node_modules/dep/index")'. - dep.default.toLowerCase(); // Error in bundler - \ No newline at end of file diff --git a/tests/baselines/reference/esbuildInterop.js b/tests/baselines/reference/esbuildInterop.js deleted file mode 100644 index 8663c50643279..0000000000000 --- a/tests/baselines/reference/esbuildInterop.js +++ /dev/null @@ -1,28 +0,0 @@ -//// [tests/cases/conformance/module/esbuildInterop.ts] //// - -//// [package.json] -{ - "name": "dep", - "version": "1.0.0", - "main": "index.js" -} - -//// [index.d.ts] -declare const _default: string; -export default _default; - -//// [package.json] -{ - "type": "module" -} - -//// [index.ts] -import dep from "dep"; -dep.toLowerCase(); // Error -dep.default.toLowerCase(); // Ok - - -//// [index.js] -import dep from "dep"; -dep.toLowerCase(); // Error -dep.default.toLowerCase(); // Ok diff --git a/tests/baselines/reference/esbuildInterop.symbols b/tests/baselines/reference/esbuildInterop.symbols deleted file mode 100644 index 3760729565157..0000000000000 --- a/tests/baselines/reference/esbuildInterop.symbols +++ /dev/null @@ -1,23 +0,0 @@ -//// [tests/cases/conformance/module/esbuildInterop.ts] //// - -=== /node_modules/dep/index.d.ts === -declare const _default: string; ->_default : Symbol(_default, Decl(index.d.ts, 0, 13)) - -export default _default; ->_default : Symbol(_default, Decl(index.d.ts, 0, 13)) - -=== /index.ts === -import dep from "dep"; ->dep : Symbol(dep, Decl(index.ts, 0, 6)) - -dep.toLowerCase(); // Error ->dep : Symbol(dep, Decl(index.ts, 0, 6)) - -dep.default.toLowerCase(); // Ok ->dep.default.toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --)) ->dep.default : Symbol(dep.default, Decl(index.d.ts, 0, 31)) ->dep : Symbol(dep, Decl(index.ts, 0, 6)) ->default : Symbol(dep.default, Decl(index.d.ts, 0, 31)) ->toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --)) - diff --git a/tests/baselines/reference/esbuildInterop.types b/tests/baselines/reference/esbuildInterop.types deleted file mode 100644 index 392b87cfa0e22..0000000000000 --- a/tests/baselines/reference/esbuildInterop.types +++ /dev/null @@ -1,27 +0,0 @@ -//// [tests/cases/conformance/module/esbuildInterop.ts] //// - -=== /node_modules/dep/index.d.ts === -declare const _default: string; ->_default : string - -export default _default; ->_default : string - -=== /index.ts === -import dep from "dep"; ->dep : typeof dep - -dep.toLowerCase(); // Error ->dep.toLowerCase() : any ->dep.toLowerCase : any ->dep : typeof dep ->toLowerCase : any - -dep.default.toLowerCase(); // Ok ->dep.default.toLowerCase() : string ->dep.default.toLowerCase : () => string ->dep.default : string ->dep : typeof dep ->default : string ->toLowerCase : () => string - diff --git a/tests/baselines/reference/webpackInterop(allowrequireesm=node16).errors.txt b/tests/baselines/reference/webpackInterop(allowrequireesm=node16).errors.txt new file mode 100644 index 0000000000000..70e55cc2d3bbf --- /dev/null +++ b/tests/baselines/reference/webpackInterop(allowrequireesm=node16).errors.txt @@ -0,0 +1,21 @@ +/main2.js(2,20): error TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("./marked-esm.mjs")' call instead. + To convert this file to an ECMAScript module, change its file extension to '.mjs' or create a local package.json file with `{ "type": "module" }`. + + +==== /main2.js (1 errors) ==== + const _1 = require("./unmarked-esm.js"); + const _2 = require("./marked-esm.mjs"); + ~~~~~~~~~~~~~~~~~~ +!!! error TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("./marked-esm.mjs")' call instead. +!!! error TS1479: To convert this file to an ECMAScript module, change its file extension to '.mjs' or create a local package.json file with `{ "type": "module" }`. + +==== /unmarked-esm.js (0 errors) ==== + export default "unmarked-esm"; + +==== /marked-esm.mjs (0 errors) ==== + export default "marked-esm"; + +==== /main1.js (0 errors) ==== + import unmarked from "./unmarked-esm.js"; + import marked from "./marked-esm.mjs"; + \ No newline at end of file diff --git a/tests/cases/conformance/module/esbuildInterop.ts b/tests/cases/conformance/module/esbuildInterop.ts index 751664a66e75a..5b31ff4f6759e 100644 --- a/tests/cases/conformance/module/esbuildInterop.ts +++ b/tests/cases/conformance/module/esbuildInterop.ts @@ -1,6 +1,6 @@ // @module: esnext // @moduleResolution: bundler -// @moduleFormatInterop: bundler, bundlernode +// @defaultIsModuleExports: auto, nodenext // @noEmit: true // @noTypesAndSymbols: true @@ -22,5 +22,5 @@ export default _default; // @Filename: /index.ts import dep from "dep"; -dep.toLowerCase(); // Error in bundlernode -dep.default.toLowerCase(); // Error in bundler +dep.toLowerCase(); // Error in nodenext +dep.default.toLowerCase(); // Error in auto diff --git a/tests/cases/conformance/module/webpackInterop.ts b/tests/cases/conformance/module/webpackInterop.ts new file mode 100644 index 0000000000000..c05df67abc901 --- /dev/null +++ b/tests/cases/conformance/module/webpackInterop.ts @@ -0,0 +1,21 @@ +// @module: preserve +// @moduleResolution: bundler +// @defaultIsModuleExports: node16 +// @allowRequireESM: always, node16 +// @noEmit: true +// @checkJs: true +// @noTypesAndSymbols: true + +// @Filename: /unmarked-esm.js +export default "unmarked-esm"; + +// @Filename: /marked-esm.mjs +export default "marked-esm"; + +// @Filename: /main1.js +import unmarked from "./unmarked-esm.js"; +import marked from "./marked-esm.mjs"; + +// @Filename: /main2.js +const _1 = require("./unmarked-esm.js"); +const _2 = require("./marked-esm.mjs"); From 82c5d0d58a009f8357eba575994429491c8bcd86 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 14 May 2024 09:38:11 -0700 Subject: [PATCH 13/13] Delete unused baseline --- .../moduleFormatInterop/tsconfig.json | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 tests/baselines/reference/config/showConfig/Shows tsconfig for single option/moduleFormatInterop/tsconfig.json diff --git a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/moduleFormatInterop/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/moduleFormatInterop/tsconfig.json deleted file mode 100644 index f4972329728c4..0000000000000 --- a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/moduleFormatInterop/tsconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "compilerOptions": { - "moduleFormatInterop": "bundler" - } -}