diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 7ce19bc264fb8..d6bc1769ea5f3 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -84,6 +84,7 @@ import { getContainingClass, getEffectiveContainerForJSDocTemplateTag, getElementOrPropertyAccessName, + getEmitModuleResolutionKind, getEmitScriptTarget, getEnclosingBlockScopeContainer, getErrorSpanForNode, @@ -235,6 +236,7 @@ import { ModifierFlags, ModuleBlock, ModuleDeclaration, + ModuleResolutionKind, Mutable, NamespaceExportDeclaration, Node, @@ -3520,6 +3522,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { if (!isBindingPattern(node.name)) { const possibleVariableDecl = node.kind === SyntaxKind.VariableDeclaration ? node : node.parent.parent; if (isInJSFile(node) && + getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Bundler && isVariableDeclarationInitializedToBareOrAccessedRequire(possibleVariableDecl) && !getJSDocTypeTag(node) && !(getCombinedModifierFlags(node) & ModifierFlags.Export) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 963981dde4743..3d9d48b1bb893 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -139,6 +139,7 @@ import { ElementFlags, EmitFlags, EmitHint, + emitModuleKindIsNonNodeESM, EmitResolver, EmitTextWriter, emptyArray, @@ -317,6 +318,7 @@ import { getResolutionModeOverrideForClause, getResolvedExternalModuleName, getResolvedModule, + getResolveJsonModule, getRestParameterElementType, getRootDeclaration, getScriptTargetFeatures, @@ -346,8 +348,8 @@ import { hasAccessorModifier, hasAmbientModifier, hasContextSensitiveParameters, - HasDecorators, hasDecorators, + HasDecorators, hasDynamicName, hasEffectiveModifier, hasEffectiveModifiers, @@ -356,8 +358,8 @@ import { hasExtension, HasIllegalDecorators, HasIllegalModifiers, - HasInitializer, hasInitializer, + HasInitializer, hasJSDocNodes, hasJSDocParameterTags, hasJsonModuleEmitEnabled, @@ -458,6 +460,7 @@ import { isConstructorTypeNode, isConstTypeReference, isDeclaration, + isDeclarationFileName, isDeclarationName, isDeclarationReadonly, isDecorator, @@ -897,6 +900,7 @@ import { setTextRangePosEnd, setValueDeclaration, ShorthandPropertyAssignment, + shouldAllowImportingTsExtension, shouldPreserveConstEnums, Signature, SignatureDeclaration, @@ -4543,6 +4547,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if ( namespace.valueDeclaration && isInJSFile(namespace.valueDeclaration) && + getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler && isVariableDeclaration(namespace.valueDeclaration) && namespace.valueDeclaration.initializer && isCommonJsRequire(namespace.valueDeclaration.initializer) @@ -4727,6 +4732,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { (isModuleDeclaration(location) ? location : location.parent && isModuleDeclaration(location.parent) && location.parent.name === location ? location.parent : undefined)?.name || (isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal; const mode = contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : currentSourceFile.impliedNodeFormat; + const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); const resolvedModule = getResolvedModule(currentSourceFile, moduleReference, mode); const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule); const sourceFile = resolvedModule @@ -4737,11 +4743,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (resolutionDiagnostic) { error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName); } + + if (resolvedModule.resolvedUsingTsExtension && isDeclarationFileName(moduleReference)) { + const importOrExport = + findAncestor(location, isImportDeclaration)?.importClause || + findAncestor(location, or(isImportEqualsDeclaration, isExportDeclaration)); + if (importOrExport && !importOrExport.isTypeOnly || findAncestor(location, isImportCall)) { + error( + errorNode, + Diagnostics.A_declaration_file_cannot_be_imported_without_import_type_Did_you_mean_to_import_an_implementation_file_0_instead, + getSuggestedImportSource(Debug.checkDefined(tryExtractTSExtension(moduleReference)))); + } + } + else if (resolvedModule.resolvedUsingTsExtension && !shouldAllowImportingTsExtension(compilerOptions, currentSourceFile.fileName)) { + const tsExtension = Debug.checkDefined(tryExtractTSExtension(moduleReference)); + error(errorNode, Diagnostics.An_import_path_can_only_end_with_a_0_extension_when_allowImportingTsExtensions_is_enabled, tsExtension); + } + if (sourceFile.symbol) { if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) { errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference); } - if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) { + if (moduleResolutionKind === ModuleResolutionKind.Node16 || moduleResolutionKind === ModuleResolutionKind.NodeNext) { const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration); const overrideClauseHost = findAncestor(location, l => isImportTypeNode(l) || isExportDeclaration(l) || isImportDeclaration(l)) as ImportTypeNode | ImportDeclaration | ExportDeclaration | undefined; const overrideClause = overrideClauseHost && isImportTypeNode(overrideClauseHost) ? overrideClauseHost.assertions?.assertClause : overrideClauseHost?.assertClause; @@ -4849,25 +4872,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else { const tsExtension = tryExtractTSExtension(moduleReference); const isExtensionlessRelativePathImport = pathIsRelative(moduleReference) && !hasExtension(moduleReference); - const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); const resolutionIsNode16OrNext = moduleResolutionKind === ModuleResolutionKind.Node16 || moduleResolutionKind === ModuleResolutionKind.NodeNext; if (tsExtension) { - const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; - const importSourceWithoutExtension = removeExtension(moduleReference, tsExtension); - let replacedImportSource = importSourceWithoutExtension; - /** - * Direct users to import source with .js extension if outputting an ES module. - * @see https://github.com/microsoft/TypeScript/issues/42151 - */ - if (moduleKind >= ModuleKind.ES2015) { - replacedImportSource += tsExtension === Extension.Mts ? ".mjs" : tsExtension === Extension.Cts ? ".cjs" : ".js"; - } - error(errorNode, diag, tsExtension, replacedImportSource); - } - else if (!compilerOptions.resolveJsonModule && + errorOnTSExtensionImport(tsExtension); + } + else if (!getResolveJsonModule(compilerOptions) && fileExtensionIs(moduleReference, Extension.Json) && - getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Classic && + moduleResolutionKind !== ModuleResolutionKind.Classic && hasJsonModuleEmitEnabled(compilerOptions)) { error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference); } @@ -4889,6 +4901,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } return undefined; + + function errorOnTSExtensionImport(tsExtension: string) { + const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + error(errorNode, diag, tsExtension, getSuggestedImportSource(tsExtension)); + } + + function getSuggestedImportSource(tsExtension: string) { + const importSourceWithoutExtension = removeExtension(moduleReference, tsExtension); + /** + * Direct users to import source with .js extension if outputting an ES module. + * @see https://github.com/microsoft/TypeScript/issues/42151 + */ + if (emitModuleKindIsNonNodeESM(moduleKind) || mode === ModuleKind.ESNext) { + return importSourceWithoutExtension + (tsExtension === Extension.Mts ? ".mjs" : tsExtension === Extension.Cts ? ".cjs" : ".js"); + } + return importSourceWithoutExtension; + } } function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void { @@ -33297,7 +33326,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // In JavaScript files, calls to any identifier 'require' are treated as external module imports - if (isInJSFile(node) && isCommonJsRequire(node)) { + if (isInJSFile(node) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler && isCommonJsRequire(node)) { return resolveExternalModuleTypeByLiteral(node.arguments![0] as StringLiteral); } @@ -42699,6 +42728,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Import equals declaration is deprecated in es6 or above grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); } + else if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler) { + grammarErrorOnNode(node, Diagnostics.Import_assignment_is_not_allowed_when_moduleResolution_is_set_to_bundler_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); + } } } } @@ -42921,6 +42953,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // system modules does not support export assignment grammarErrorOnNode(node, Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system); } + else if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler) { + grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_moduleResolution_is_set_to_bundler_Consider_using_export_default_or_another_module_format_instead); + } } } @@ -44015,7 +44050,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // 4). type A = import("./f/*gotToDefinitionHere*/oo") if ((isExternalModuleImportEqualsDeclaration(node.parent.parent) && getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) || ((node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration) && (node.parent as ImportDeclaration).moduleSpecifier === node) || - ((isInJSFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || isImportCall(node.parent)) || + ((isInJSFile(node) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Bundler && isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || isImportCall(node.parent)) || (isLiteralTypeNode(node.parent) && isLiteralImportTypeNode(node.parent.parent) && node.parent.parent.argument === node.parent) ) { return resolveExternalModuleName(node, node as LiteralExpression, ignoreErrors); @@ -47321,4 +47356,4 @@ class SymbolTrackerImpl implements SymbolTracker { private onDiagnosticReported() { this.context.reportedDiagnostic = true; } -} \ No newline at end of file +} diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 97a09f716345e..e8f5452edfcba 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -965,6 +965,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [ classic: ModuleResolutionKind.Classic, node16: ModuleResolutionKind.Node16, nodenext: ModuleResolutionKind.NodeNext, + bundler: ModuleResolutionKind.Bundler, })), affectsModuleResolution: true, paramType: Diagnostics.STRATEGY, @@ -1081,6 +1082,41 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [ category: Diagnostics.Modules, description: Diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module, }, + { + name: "allowImportingTsExtensions", + type: "boolean", + affectsModuleResolution: true, + category: Diagnostics.Modules, + description: Diagnostics.Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noEmit_or_emitDeclarationOnly_to_be_set, + defaultValueDescription: false, + }, + { + name: "resolvePackageJsonExports", + type: "boolean", + affectsModuleResolution: true, + category: Diagnostics.Modules, + description: Diagnostics.Use_the_package_json_exports_field_when_resolving_package_imports, + defaultValueDescription: Diagnostics.true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false, + }, + { + name: "resolvePackageJsonImports", + type: "boolean", + affectsModuleResolution: true, + category: Diagnostics.Modules, + description: Diagnostics.Use_the_package_json_imports_field_when_resolving_imports, + defaultValueDescription: Diagnostics.true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false, + }, + { + name: "customConditions", + type: "list", + element: { + name: "condition", + type: "string", + }, + affectsModuleResolution: true, + category: Diagnostics.Modules, + description: Diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports, + }, // Source Maps { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e146cce88c8cb..ad3d9ec3e3eba 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3563,6 +3563,10 @@ "category": "Error", "code": 2845 }, + "A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file '{0}' instead?": { + "category": "Error", + "code": 2846 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", @@ -4221,6 +4225,26 @@ "category": "Error", "code": 5095 }, + "Option 'allowImportingTsExtensions' can only be used when 'moduleResolution' is set to 'bundler' and either 'noEmit' or 'emitDeclarationOnly' is set.": { + "category": "Error", + "code": 5096 + }, + "An import path can only end with a '{0}' extension when 'allowImportingTsExtensions' is enabled.": { + "category": "Error", + "code": 5097 + }, + "Option '{0}' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'.": { + "category": "Error", + "code": 5098 + }, + "Import assignment is not allowed when 'moduleResolution' is set to 'bundler'. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead.": { + "category": "Error", + "code": 5099 + }, + "Export assignment cannot be used when 'moduleResolution' is set to 'bundler'. Consider using 'export default' or another module format instead.": { + "category": "Error", + "code": 5100 + }, "Generates a sourcemap for each corresponding '.d.ts' file.": { "category": "Message", @@ -4443,10 +4467,6 @@ "category": "Message", "code": 6066 }, - "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).": { - "category": "Message", - "code": 6069 - }, "Initializes a TypeScript project and creates a tsconfig.json file.": { "category": "Message", "code": 6070 @@ -5430,6 +5450,26 @@ "category": "Message", "code": 6406 }, + "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.": { + "category": "Message", + "code": 6407 + }, + "Use the package.json 'exports' field when resolving package imports.": { + "category": "Message", + "code": 6408 + }, + "Use the package.json 'imports' field when resolving imports.": { + "category": "Message", + "code": 6409 + }, + "Conditions to set in addition to the resolver-specific defaults when resolving imports.": { + "category": "Message", + "code": 6410 + }, + "`true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.": { + "category": "Message", + "code": 6411 + }, "The expected type comes from property '{0}' which is declared here on type '{1}'": { "category": "Message", diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index fd9cf539fc333..5a1c504bc2515 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -2,6 +2,7 @@ import { append, appendIfUnique, arrayFrom, + arrayIsEqualTo, changeAnyExtension, CharacterCodes, combinePaths, @@ -9,10 +10,12 @@ import { comparePaths, Comparison, CompilerOptions, + concatenate, contains, containsPath, createCompilerDiagnostic, Debug, + deduplicate, Diagnostic, DiagnosticMessage, DiagnosticReporter, @@ -47,12 +50,14 @@ import { getPathsBasePath, getPossibleOriginalInputExtensionForExtension, getRelativePathFromDirectory, + getResolveJsonModule, getRootLength, hasJSFileExtension, hasProperty, hasTrailingDirectorySeparator, hostGetCanonicalFileName, isArray, + isDeclarationFileName, isExternalModuleNameRelative, isRootedDiskPath, isString, @@ -94,6 +99,7 @@ import { startsWith, stringContains, supportedDeclarationExtensions, + supportedTSExtensionsFlat, supportedTSImplementationExtensions, toPath, tryExtractTSExtension, @@ -128,7 +134,7 @@ function withPackageId(packageInfo: PackageJsonInfo | undefined, r: PathAndExten }; } } - return r && { path: r.path, extension: r.ext, packageId }; + return r && { path: r.path, extension: r.ext, packageId, resolvedUsingTsExtension: r.resolvedUsingTsExtension }; } function noPackageId(r: PathAndExtension | undefined): Resolved | undefined { @@ -138,7 +144,7 @@ function noPackageId(r: PathAndExtension | undefined): Resolved | undefined { function removeIgnoredPackageId(r: Resolved | undefined): PathAndExtension | undefined { if (r) { Debug.assert(r.packageId === undefined); - return { path: r.path, ext: r.extension }; + return { path: r.path, ext: r.extension, resolvedUsingTsExtension: r.resolvedUsingTsExtension }; } } @@ -157,6 +163,7 @@ interface Resolved { * Note: This is a file name with preserved original casing, not a normalized `Path`. */ originalPath?: string | true; + resolvedUsingTsExtension: boolean | undefined; } /** Result of trying to resolve a module at a file. Needs to have 'packageId' added later. */ @@ -164,6 +171,7 @@ interface PathAndExtension { path: string; // (Use a different name than `extension` to make sure Resolved isn't assignable to PathAndExtension.) ext: Extension; + resolvedUsingTsExtension: boolean | undefined; } /** @@ -215,7 +223,14 @@ function createResolvedModuleWithFailedLookupLocations( return resultFromCache; } return { - resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId }, + resolvedModule: resolved && { + resolvedFileName: resolved.path, + originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, + extension: resolved.extension, + isExternalLibraryImport, + packageId: resolved.packageId, + resolvedUsingTsExtension: !!resolved.resolvedUsingTsExtension, + }, failedLookupLocations: initializeResolutionField(failedLookupLocations), affectingLocations: initializeResolutionField(affectingLocations), resolutionDiagnostics: initializeResolutionField(diagnostics), @@ -488,7 +503,7 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string const failedLookupLocations: string[] = []; const affectingLocations: string[] = []; - let features = getDefaultNodeResolutionFeatures(options); + let features = getNodeResolutionFeatures(options); // Unlike `import` statements, whose mode-calculating APIs are all guaranteed to return `undefined` if we're in an un-mode-ed module resolution // setting, type references will return their target mode regardless of options because of how the parser works, so we guard against the mode being // set in a non-modal module resolution setting here. Do note that our behavior is not particularly well defined when these mode-overriding imports @@ -499,7 +514,7 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string if (resolutionMode === ModuleKind.ESNext && (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext)) { features |= NodeResolutionFeatures.EsmMode; } - const conditions = features & NodeResolutionFeatures.Exports ? features & NodeResolutionFeatures.EsmMode ? ["node", "import", "types"] : ["node", "require", "types"] : []; + const conditions = features & NodeResolutionFeatures.Exports ? getConditions(options, !!(features & NodeResolutionFeatures.EsmMode)) : []; const diagnostics: Diagnostic[] = []; const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, @@ -614,10 +629,44 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string } } -function getDefaultNodeResolutionFeatures(options: CompilerOptions) { - return getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 ? NodeResolutionFeatures.Node16Default : - getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext ? NodeResolutionFeatures.NodeNextDefault : - NodeResolutionFeatures.None; +function getNodeResolutionFeatures(options: CompilerOptions) { + let features = NodeResolutionFeatures.None; + switch (getEmitModuleResolutionKind(options)) { + case ModuleResolutionKind.Node16: + features = NodeResolutionFeatures.Node16Default; + break; + case ModuleResolutionKind.NodeNext: + features = NodeResolutionFeatures.NodeNextDefault; + break; + case ModuleResolutionKind.Bundler: + features = NodeResolutionFeatures.BundlerDefault; + break; + } + if (options.resolvePackageJsonExports) { + features |= NodeResolutionFeatures.Exports; + } + else if (options.resolvePackageJsonExports === false) { + features &= ~NodeResolutionFeatures.Exports; + } + if (options.resolvePackageJsonImports) { + features |= NodeResolutionFeatures.Imports; + } + else if (options.resolvePackageJsonImports === false) { + features &= ~NodeResolutionFeatures.Imports; + } + return features; +} + +function getConditions(options: CompilerOptions, esmMode?: boolean) { + // conditions are only used by the node16/nodenext/bundler resolvers - there's no priority order in the list, + // it's essentially a set (priority is determined by object insertion order in the object we look at). + const conditions = esmMode || getEmitModuleResolutionKind(options) === ModuleResolutionKind.Bundler + ? ["node", "import"] + : ["node", "require"]; + if (!options.noDtsResolution) { + conditions.push("types"); + } + return concatenate(conditions, options.customConditions); } /** @@ -1235,6 +1284,9 @@ export function resolveModuleName(moduleName: string, containingFile: string, co case ModuleResolutionKind.Classic: result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference); break; + case ModuleResolutionKind.Bundler: + result = bundlerModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference); + break; default: return Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`); } @@ -1489,6 +1541,8 @@ export enum NodeResolutionFeatures { NodeNextDefault = AllFeatures, + BundlerDefault = Imports | SelfName | Exports | ExportsPatternTrailers, + EsmMode = 1 << 5, } @@ -1528,7 +1582,7 @@ function nodeNextModuleNameResolverWorker(features: NodeResolutionFeatures, modu // es module file or cjs-like input file, use a variant of the legacy cjs resolver that supports the selected modern features const esmMode = resolutionMode === ModuleKind.ESNext ? NodeResolutionFeatures.EsmMode : 0; let extensions = compilerOptions.noDtsResolution ? Extensions.ImplementationFiles : Extensions.TypeScript | Extensions.JavaScript | Extensions.Declaration; - if (compilerOptions.resolveJsonModule) { + if (getResolveJsonModule(compilerOptions)) { extensions |= Extensions.Json; } return nodeModuleNameResolverWorker(features | esmMode, moduleName, containingDirectory, compilerOptions, host, cache, extensions, /*isConfigLookup*/ false, redirectedReference); @@ -1547,6 +1601,15 @@ function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host: /*redirectedReferences*/ undefined); } +export function bundlerModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations { + const containingDirectory = getDirectoryPath(containingFile); + let extensions = compilerOptions.noDtsResolution ? Extensions.ImplementationFiles : Extensions.TypeScript | Extensions.JavaScript | Extensions.Declaration; + if (getResolveJsonModule(compilerOptions)) { + extensions |= Extensions.Json; + } + return nodeModuleNameResolverWorker(getNodeResolutionFeatures(compilerOptions), moduleName, containingDirectory, compilerOptions, host, cache, extensions, /*isConfigLookup*/ false, redirectedReference); +} + export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; /** @internal */ export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations; // eslint-disable-line @typescript-eslint/unified-signatures export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, isConfigLookup?: boolean): ResolvedModuleWithFailedLookupLocations { @@ -1556,10 +1619,10 @@ export function nodeModuleNameResolver(moduleName: string, containingFile: strin } else if (compilerOptions.noDtsResolution) { extensions = Extensions.ImplementationFiles; - if (compilerOptions.resolveJsonModule) extensions |= Extensions.Json; + if (getResolveJsonModule(compilerOptions)) extensions |= Extensions.Json; } else { - extensions = compilerOptions.resolveJsonModule + extensions = getResolveJsonModule(compilerOptions) ? Extensions.TypeScript | Extensions.JavaScript | Extensions.Declaration | Extensions.Json : Extensions.TypeScript | Extensions.JavaScript | Extensions.Declaration; } @@ -1571,12 +1634,7 @@ function nodeModuleNameResolverWorker(features: NodeResolutionFeatures, moduleNa const failedLookupLocations: string[] = []; const affectingLocations: string[] = []; - // conditions are only used by the node16/nodenext resolver - there's no priority order in the list, - //it's essentially a set (priority is determined by object insertion order in the object we look at). - const conditions = features & NodeResolutionFeatures.EsmMode ? ["node", "import", "types"] : ["node", "require", "types"]; - if (compilerOptions.noDtsResolution) { - conditions.pop(); - } + const conditions = getConditions(compilerOptions, !!(features & NodeResolutionFeatures.EsmMode)); const diagnostics: Diagnostic[] = []; const state: ModuleResolutionState = { @@ -1720,7 +1778,7 @@ function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, } } // esm mode relative imports shouldn't do any directory lookups (either inside `package.json` - // files or implicit `index.js`es). This is a notable depature from cjs norms, where `./foo/pkg` + // files or implicit `index.js`es). This is a notable departure from cjs norms, where `./foo/pkg` // could have been redirected by `./foo/pkg/package.json` to an arbitrary location! if (!(state.features & NodeResolutionFeatures.EsmMode)) { return loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson); @@ -1795,7 +1853,12 @@ function loadModuleFromFile(extensions: Extensions, candidate: string, onlyRecor function loadModuleFromFileNoImplicitExtensions(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" - if (hasJSFileExtension(candidate) || extensions & Extensions.Json && fileExtensionIs(candidate, Extension.Json)) { + if (hasJSFileExtension(candidate) || + extensions & Extensions.Json && fileExtensionIs(candidate, Extension.Json) || + extensions & (Extensions.TypeScript | Extensions.Declaration) + && moduleResolutionSupportsResolvingTsExtensions(state.compilerOptions) + && fileExtensionIsOneOf(candidate, supportedTSExtensionsFlat) + ) { const extensionless = removeFileExtension(candidate); const extension = candidate.substring(extensionless.length); if (state.traceEnabled) { @@ -1810,7 +1873,7 @@ function loadJSOrExactTSFileName(extensions: Extensions, candidate: string, only extensions & Extensions.Declaration && fileExtensionIsOneOf(candidate, supportedDeclarationExtensions) ) { const result = tryFile(candidate, onlyRecordFailures, state); - return result !== undefined ? { path: candidate, ext: tryExtractTSExtension(candidate) as Extension } : undefined; + return result !== undefined ? { path: candidate, ext: tryExtractTSExtension(candidate) as Extension, resolvedUsingTsExtension: undefined } : undefined; } return loadModuleFromFileNoImplicitExtensions(extensions, candidate, onlyRecordFailures, state); @@ -1854,6 +1917,13 @@ function tryAddingExtensions(candidate: string, extensions: Extensions, original if (result) return result; } return undefined; + case Extension.Ts: + case Extension.Tsx: + case Extension.Dts: + if (moduleResolutionSupportsResolvingTsExtensions(state.compilerOptions) && extensionIsOk(extensions, originalExtension)) { + return tryExtension(originalExtension, /*resolvedUsingTsExtension*/ true); + } + // falls through default: return extensions & Extensions.TypeScript && (tryExtension(Extension.Ts) || tryExtension(Extension.Tsx)) || extensions & Extensions.Declaration && tryExtension(Extension.Dts) @@ -1863,9 +1933,9 @@ function tryAddingExtensions(candidate: string, extensions: Extensions, original } - function tryExtension(ext: Extension): PathAndExtension | undefined { + function tryExtension(ext: Extension, resolvedUsingTsExtension?: boolean): PathAndExtension | undefined { const path = tryFile(candidate + ext, onlyRecordFailures, state); - return path === undefined ? undefined : { path, ext }; + return path === undefined ? undefined : { path, ext, resolvedUsingTsExtension }; } } @@ -1921,26 +1991,30 @@ export function getEntrypointsFromPackageJsonInfo( let entrypoints: string[] | undefined; const extensions = Extensions.TypeScript | Extensions.Declaration | (resolveJs ? Extensions.JavaScript : 0); - const features = getDefaultNodeResolutionFeatures(options); - const requireState = getTemporaryModuleResolutionState(cache?.getPackageJsonInfoCache(), host, options); - requireState.conditions = ["node", "require", "types"]; - requireState.requestContainingDirectory = packageJsonInfo.packageDirectory; - const requireResolution = loadNodeModuleFromDirectoryWorker( + const features = getNodeResolutionFeatures(options); + const loadPackageJsonMainState = getTemporaryModuleResolutionState(cache?.getPackageJsonInfoCache(), host, options); + loadPackageJsonMainState.conditions = getConditions(options); + loadPackageJsonMainState.requestContainingDirectory = packageJsonInfo.packageDirectory; + const mainResolution = loadNodeModuleFromDirectoryWorker( extensions, packageJsonInfo.packageDirectory, /*onlyRecordFailures*/ false, - requireState, + loadPackageJsonMainState, packageJsonInfo.contents.packageJsonContent, - getVersionPathsOfPackageJsonInfo(packageJsonInfo, requireState)); - entrypoints = append(entrypoints, requireResolution?.path); + getVersionPathsOfPackageJsonInfo(packageJsonInfo, loadPackageJsonMainState)); + entrypoints = append(entrypoints, mainResolution?.path); if (features & NodeResolutionFeatures.Exports && packageJsonInfo.contents.packageJsonContent.exports) { - for (const conditions of [["node", "import", "types"], ["node", "require", "types"]]) { - const exportState = { ...requireState, failedLookupLocations: [], conditions }; + const conditionSets = deduplicate( + [getConditions(options, /*esmMode*/ true), getConditions(options, /*esmMode*/ false)], + arrayIsEqualTo + ); + for (const conditions of conditionSets) { + const loadPackageJsonExportsState = { ...loadPackageJsonMainState, failedLookupLocations: [], conditions }; const exportResolutions = loadEntrypointsFromExportMap( packageJsonInfo, packageJsonInfo.contents.packageJsonContent.exports, - exportState, + loadPackageJsonExportsState, extensions); if (exportResolutions) { for (const resolution of exportResolutions) { @@ -2046,7 +2120,7 @@ export interface PackageJsonInfoContents { * * @internal */ - export function getPackageScopeForPath(fileName: string, state: ModuleResolutionState): PackageJsonInfo | undefined { +export function getPackageScopeForPath(fileName: string, state: ModuleResolutionState): PackageJsonInfo | undefined { const parts = getPathComponents(fileName); parts.pop(); while (parts.length > 0) { @@ -2179,9 +2253,9 @@ function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: st } /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ -function resolvedIfExtensionMatches(extensions: Extensions, path: string): PathAndExtension | undefined { +function resolvedIfExtensionMatches(extensions: Extensions, path: string, resolvedUsingTsExtension?: boolean): PathAndExtension | undefined { const ext = tryGetExtensionFromPath(path); - return ext !== undefined && extensionIsOk(extensions, ext) ? { path, ext } : undefined; + return ext !== undefined && extensionIsOk(extensions, ext) ? { path, ext, resolvedUsingTsExtension } : undefined; } /** True if `extension` is one of the supported `extensions`. */ @@ -2372,7 +2446,13 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo traceIfEnabled(state, Diagnostics.Using_0_subpath_1_with_target_2, "imports", key, combinedLookup); traceIfEnabled(state, Diagnostics.Resolving_module_0_from_1, combinedLookup, scope.packageDirectory + "/"); const result = nodeModuleNameResolverWorker(state.features, combinedLookup, scope.packageDirectory + "/", state.compilerOptions, state.host, cache, extensions, /*isConfigLookup*/ false, redirectedReference); - return toSearchResult(result.resolvedModule ? { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId, originalPath: result.resolvedModule.originalPath } : undefined); + return toSearchResult(result.resolvedModule ? { + path: result.resolvedModule.resolvedFileName, + extension: result.resolvedModule.extension, + packageId: result.resolvedModule.packageId, + originalPath: result.resolvedModule.originalPath, + resolvedUsingTsExtension: result.resolvedModule.resolvedUsingTsExtension + } : undefined); } if (state.traceEnabled) { trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); @@ -2753,7 +2833,7 @@ function tryLoadModuleUsingPaths(extensions: Extensions, moduleName: string, bas if (extension !== undefined) { const path = tryFile(candidate, onlyRecordFailures, state); if (path !== undefined) { - return noPackageId({ path, ext: extension }); + return noPackageId({ path, ext: extension, resolvedUsingTsExtension: undefined }); } } return loader(extensions, candidate, onlyRecordFailures || !directoryProbablyExists(getDirectoryPath(candidate), state.host), state); @@ -2813,7 +2893,15 @@ function tryFindNonRelativeModuleNameInCache(cache: NonRelativeModuleNameResolut trace(state.host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory); } state.resultFromCache = result; - return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, originalPath: result.resolvedModule.originalPath || true, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; + return { + value: result.resolvedModule && { + path: result.resolvedModule.resolvedFileName, + originalPath: result.resolvedModule.originalPath || true, + extension: result.resolvedModule.extension, + packageId: result.resolvedModule.packageId, + resolvedUsingTsExtension: result.resolvedModule.resolvedUsingTsExtension + } + }; } } @@ -2880,6 +2968,18 @@ export function classicNameResolver(moduleName: string, containingFile: string, } } +export function moduleResolutionSupportsResolvingTsExtensions(compilerOptions: CompilerOptions) { + return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler; +} + +// Program errors validate that `noEmit` or `emitDeclarationOnly` is also set, +// so this function doesn't check them to avoid propagating errors. +export function shouldAllowImportingTsExtension(compilerOptions: CompilerOptions, fromFileName?: string) { + return moduleResolutionSupportsResolvingTsExtensions(compilerOptions) && ( + !!compilerOptions.allowImportingTsExtensions || + fromFileName && isDeclarationFileName(fromFileName)); +} + /** * A host may load a module from a global cache of typings. * This is the minumum code needed to expose that functionality; the rest is in the host. diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index c21a26c7dcb28..351d98a24bd19 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -34,9 +34,9 @@ import { GetCanonicalFileName, getDirectoryPath, getEmitModuleResolutionKind, - getImpliedNodeFormatForFile, getModeForResolutionAtIndex, getModuleNameStringLiteralAt, + getModuleSpecifierEndingPreference, getNodeModulePathParts, getNormalizedAbsolutePath, getOwnKeys, @@ -54,6 +54,7 @@ import { Identifier, isAmbientModule, isApplicableVersionedTypesKey, + isDeclarationFileName, isExternalModuleAugmentation, isExternalModuleNameRelative, isModuleBlock, @@ -71,9 +72,9 @@ import { ModuleDeclaration, ModuleKind, ModulePath, - ModuleResolutionHost, ModuleResolutionKind, ModuleSpecifierCache, + ModuleSpecifierEnding, ModuleSpecifierOptions, ModuleSpecifierResolutionHost, NodeFlags, @@ -89,6 +90,7 @@ import { ResolutionMode, resolvePath, ScriptKind, + shouldAllowImportingTsExtension, some, SourceFile, startsWith, @@ -107,61 +109,63 @@ import { // Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers. const enum RelativePreference { Relative, NonRelative, Shortest, ExternalNonRelative } -// See UserPreferences#importPathEnding -const enum Ending { Minimal, Index, JsExtension } // Processed preferences interface Preferences { readonly relativePreference: RelativePreference; - readonly ending: Ending; + /** + * @param syntaxImpliedNodeFormat Used when the import syntax implies ESM or CJS irrespective of the mode of the file. + */ + getAllowedEndingsInPreferredOrder(syntaxImpliedNodeFormat?: SourceFile["impliedNodeFormat"]): ModuleSpecifierEnding[]; } -function getPreferences(host: ModuleSpecifierResolutionHost, { importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences, compilerOptions: CompilerOptions, importingSourceFile: SourceFile): Preferences { +function getPreferences( + { importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences, + compilerOptions: CompilerOptions, + importingSourceFile: SourceFile, + oldImportSpecifier?: string, +): Preferences { + const preferredEnding = getPreferredEnding(); return { relativePreference: + oldImportSpecifier !== undefined ? (isExternalModuleNameRelative(oldImportSpecifier) ? + RelativePreference.Relative : + RelativePreference.NonRelative) : importModuleSpecifierPreference === "relative" ? RelativePreference.Relative : importModuleSpecifierPreference === "non-relative" ? RelativePreference.NonRelative : importModuleSpecifierPreference === "project-relative" ? RelativePreference.ExternalNonRelative : RelativePreference.Shortest, - ending: getEnding(), - }; - function getEnding(): Ending { - switch (importModuleSpecifierEnding) { - case "minimal": return Ending.Minimal; - case "index": return Ending.Index; - case "js": return Ending.JsExtension; - default: return usesJsExtensionOnImports(importingSourceFile) || isFormatRequiringExtensions(compilerOptions, importingSourceFile.path, host) ? Ending.JsExtension - : getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs ? Ending.Index : Ending.Minimal; - } - } -} - -function getPreferencesForUpdate(compilerOptions: CompilerOptions, oldImportSpecifier: string, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Preferences { - return { - relativePreference: isExternalModuleNameRelative(oldImportSpecifier) ? RelativePreference.Relative : RelativePreference.NonRelative, - ending: hasJSFileExtension(oldImportSpecifier) || isFormatRequiringExtensions(compilerOptions, importingSourceFileName, host) ? - Ending.JsExtension : - getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs || endsWith(oldImportSpecifier, "index") ? Ending.Index : Ending.Minimal, + getAllowedEndingsInPreferredOrder: syntaxImpliedNodeFormat => { + if ((syntaxImpliedNodeFormat ?? importingSourceFile.impliedNodeFormat) === ModuleKind.ESNext) { + if (shouldAllowImportingTsExtension(compilerOptions, importingSourceFile.fileName)) { + return [ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.JsExtension]; + } + return [ModuleSpecifierEnding.JsExtension]; + } + if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Classic) { + return [ModuleSpecifierEnding.Index, ModuleSpecifierEnding.JsExtension]; + } + switch (preferredEnding) { + case ModuleSpecifierEnding.JsExtension: return [ModuleSpecifierEnding.JsExtension, ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.Index]; + case ModuleSpecifierEnding.TsExtension: return [ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.JsExtension, ModuleSpecifierEnding.Index]; + case ModuleSpecifierEnding.Index: return [ModuleSpecifierEnding.Index, ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.JsExtension]; + case ModuleSpecifierEnding.Minimal: return [ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.Index, ModuleSpecifierEnding.JsExtension]; + default: Debug.assertNever(preferredEnding); + } + }, }; -} -function isFormatRequiringExtensions(compilerOptions: CompilerOptions, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost) { - if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16 - && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) { - return false; + function getPreferredEnding(): ModuleSpecifierEnding { + if (oldImportSpecifier !== undefined) { + if (hasJSFileExtension(oldImportSpecifier)) return ModuleSpecifierEnding.JsExtension; + if (endsWith(oldImportSpecifier, "/index")) return ModuleSpecifierEnding.Index; + } + return getModuleSpecifierEndingPreference( + importModuleSpecifierEnding, + importingSourceFile.impliedNodeFormat, + compilerOptions, + importingSourceFile); } - return getImpliedNodeFormatForFile(importingSourceFileName, host.getPackageJsonInfoCache?.(), getModuleResolutionHost(host), compilerOptions) !== ModuleKind.CommonJS; -} - -function getModuleResolutionHost(host: ModuleSpecifierResolutionHost): ModuleResolutionHost { - return { - fileExists: host.fileExists, - readFile: Debug.checkDefined(host.readFile), - directoryExists: host.directoryExists, - getCurrentDirectory: host.getCurrentDirectory, - realpath: host.realpath, - useCaseSensitiveFileNames: host.useCaseSensitiveFileNames?.(), - }; } // `importingSourceFile` and `importingSourceFileName`? Why not just use `importingSourceFile.path`? @@ -178,7 +182,7 @@ export function updateModuleSpecifier( oldImportSpecifier: string, options: ModuleSpecifierOptions = {}, ): string | undefined { - const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getPreferencesForUpdate(compilerOptions, oldImportSpecifier, importingSourceFileName, host), {}, options); + const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getPreferences({}, compilerOptions, importingSourceFile, oldImportSpecifier), {}, options); if (res === oldImportSpecifier) return undefined; return res; } @@ -198,7 +202,7 @@ export function getModuleSpecifier( host: ModuleSpecifierResolutionHost, options: ModuleSpecifierOptions = {}, ): string { - return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getPreferences(host, {}, compilerOptions, importingSourceFile), {}, options); + return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getPreferences({}, compilerOptions, importingSourceFile), {}, options); } /** @internal */ @@ -331,7 +335,7 @@ function computeModuleSpecifiers( options: ModuleSpecifierOptions = {}, ): readonly string[] { const info = getInfo(importingSourceFile.path, host); - const preferences = getPreferences(host, userPreferences, compilerOptions, importingSourceFile); + const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile); const existingSpecifier = forEach(modulePaths, modulePath => forEach( host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)), reason => { @@ -423,17 +427,18 @@ function getInfo(importingSourceFileName: Path, host: ModuleSpecifierResolutionH return { getCanonicalFileName, importingSourceFileName, sourceDirectory }; } -function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { ending, relativePreference }: Preferences): string; -function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { ending, relativePreference }: Preferences, pathsOnly?: boolean): string | undefined; -function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { ending, relativePreference }: Preferences, pathsOnly?: boolean): string | undefined { +function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, preferences: Preferences): string; +function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, preferences: Preferences, pathsOnly?: boolean): string | undefined; +function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { getAllowedEndingsInPreferredOrder: getAllowedEndingsInPrefererredOrder, relativePreference }: Preferences, pathsOnly?: boolean): string | undefined { const { baseUrl, paths, rootDirs } = compilerOptions; if (pathsOnly && !paths) { return undefined; } const { sourceDirectory, getCanonicalFileName } = info; - const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) || - removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions); + const allowedEndings = getAllowedEndingsInPrefererredOrder(importMode); + const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, allowedEndings, compilerOptions) || + processEnding(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), allowedEndings, compilerOptions); if (!baseUrl && !paths || relativePreference === RelativePreference.Relative) { return pathsOnly ? undefined : relativePath; } @@ -444,12 +449,12 @@ function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOpt return pathsOnly ? undefined : relativePath; } - const fromPaths = paths && tryGetModuleNameFromPaths(relativeToBaseUrl, paths, getAllowedEndings(ending, compilerOptions, importMode), host, compilerOptions); + const fromPaths = paths && tryGetModuleNameFromPaths(relativeToBaseUrl, paths, allowedEndings, host, compilerOptions); if (pathsOnly) { return fromPaths; } - const maybeNonRelative = fromPaths === undefined && baseUrl !== undefined ? removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions) : fromPaths; + const maybeNonRelative = fromPaths === undefined && baseUrl !== undefined ? processEnding(relativeToBaseUrl, allowedEndings, compilerOptions) : fromPaths; if (!maybeNonRelative) { return relativePath; } @@ -508,10 +513,6 @@ export function countPathComponents(path: string): number { return count; } -function usesJsExtensionOnImports({ imports }: SourceFile): boolean { - return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasJSFileExtension(text) : undefined) || false; -} - function comparePathsByRedirectAndNumberOfDirectorySeparators(a: ModulePath, b: ModulePath) { return compareBooleans(b.isRedirect, a.isRedirect) || compareNumberOfDirectorySeparators(a.path, b.path); } @@ -698,19 +699,7 @@ function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol, checker: TypeCh } } -function getAllowedEndings(preferredEnding: Ending, compilerOptions: CompilerOptions, importMode: ResolutionMode) { - if (getEmitModuleResolutionKind(compilerOptions) >= ModuleResolutionKind.Node16 && importMode === ModuleKind.ESNext) { - return [Ending.JsExtension]; - } - switch (preferredEnding) { - case Ending.JsExtension: return [Ending.JsExtension, Ending.Minimal, Ending.Index]; - case Ending.Index: return [Ending.Index, Ending.Minimal, Ending.JsExtension]; - case Ending.Minimal: return [Ending.Minimal, Ending.Index, Ending.JsExtension]; - default: Debug.assertNever(preferredEnding); - } -} - -function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike, allowedEndings: Ending[], host: ModuleSpecifierResolutionHost, compilerOptions: CompilerOptions): string | undefined { +function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike, allowedEndings: ModuleSpecifierEnding[], host: ModuleSpecifierResolutionHost, compilerOptions: CompilerOptions): string | undefined { for (const key in paths) { for (const patternText of paths[key]) { const pattern = normalizePath(patternText); @@ -751,9 +740,9 @@ function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike ({ + const candidates: { ending: ModuleSpecifierEnding | undefined, value: string }[] = allowedEndings.map(ending => ({ ending, - value: removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions) + value: processEnding(relativeToBaseUrl, [ending], compilerOptions) })); if (tryGetExtensionFromPath(pattern)) { candidates.push({ ending: undefined, value: relativeToBaseUrl }); @@ -774,23 +763,23 @@ function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike c.ending !== Ending.Minimal && pattern === c.value) || - some(candidates, c => c.ending === Ending.Minimal && pattern === c.value && validateEnding(c)) + some(candidates, c => c.ending !== ModuleSpecifierEnding.Minimal && pattern === c.value) || + some(candidates, c => c.ending === ModuleSpecifierEnding.Minimal && pattern === c.value && validateEnding(c)) ) { return key; } } } - function validateEnding({ ending, value }: { ending: Ending | undefined, value: string }) { + function validateEnding({ ending, value }: { ending: ModuleSpecifierEnding | undefined, value: string }) { // Optimization: `removeExtensionAndIndexPostFix` can query the file system (a good bit) if `ending` is `Minimal`, the basename // is 'index', and a `host` is provided. To avoid that until it's unavoidable, we ran the function with no `host` above. Only // here, after we've checked that the minimal ending is indeed a match (via the length and prefix/suffix checks / `some` calls), // do we check that the host-validated result is consistent with the answer we got before. If it's not, it falls back to the - // `Ending.Index` result, which should already be in the list of candidates if `Minimal` was. (Note: the assumption here is + // `ModuleSpecifierEnding.Index` result, which should already be in the list of candidates if `Minimal` was. (Note: the assumption here is // that every module resolution mode that supports dropping extensions also supports dropping `/index`. Like literally // everything else in this file, this logic needs to be updated if that's not true in some future module resolution mode.) - return ending !== Ending.Minimal || value === removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions, host); + return ending !== ModuleSpecifierEnding.Minimal || value === processEnding(relativeToBaseUrl, [ending], compilerOptions, host); } } @@ -865,7 +854,7 @@ function tryGetModuleNameFromExports(options: CompilerOptions, targetFilePath: s return undefined; } -function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, ending: Ending, compilerOptions: CompilerOptions): string | undefined { +function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, allowedEndings: readonly ModuleSpecifierEnding[], compilerOptions: CompilerOptions): string | undefined { const normalizedTargetPaths = getPathsRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); if (normalizedTargetPaths === undefined) { return undefined; @@ -879,10 +868,7 @@ function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileNam if (!shortest) { return undefined; } - - return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Classic - ? removeFileExtension(shortest) - : removeExtensionAndIndexPostFix(shortest, ending, compilerOptions); + return processEnding(shortest, allowedEndings, compilerOptions); } function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCanonicalFileName, sourceDirectory }: Info, importingSourceFile: SourceFile, host: ModuleSpecifierResolutionHost, options: CompilerOptions, userPreferences: UserPreferences, packageNameOnly?: boolean, overrideMode?: ResolutionMode): string | undefined { @@ -896,7 +882,8 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan // Simplify the full file path to something that can be resolved by Node. - const preferences = getPreferences(host, userPreferences, options, importingSourceFile); + const preferences = getPreferences(userPreferences, options, importingSourceFile); + const allowedEndings = preferences.getAllowedEndingsInPreferredOrder(); let moduleSpecifier = path; let isPackageRootPath = false; if (!packageNameOnly) { @@ -923,7 +910,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan // try with next level of directory packageRootIndex = path.indexOf(directorySeparator, packageRootIndex + 1); if (packageRootIndex === -1) { - moduleSpecifier = removeExtensionAndIndexPostFix(moduleFileName, preferences.ending, options, host); + moduleSpecifier = processEnding(moduleFileName, allowedEndings, options, host); break; } } @@ -979,7 +966,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan const fromPaths = tryGetModuleNameFromPaths( subModuleName, versionPaths.paths, - getAllowedEndings(preferences.ending, options, importMode), + allowedEndings, host, options ); @@ -1036,13 +1023,22 @@ function getPathsRelativeToRootDirs(path: string, rootDirs: readonly string[], g }); } -function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, options: CompilerOptions, host?: ModuleSpecifierResolutionHost): string { - if (fileExtensionIsOneOf(fileName, [Extension.Json, Extension.Mjs, Extension.Cjs])) return fileName; +function processEnding(fileName: string, allowedEndings: readonly ModuleSpecifierEnding[], options: CompilerOptions, host?: ModuleSpecifierResolutionHost): string { + if (fileExtensionIsOneOf(fileName, [Extension.Json, Extension.Mjs, Extension.Cjs])) { + return fileName; + } + const noExtension = removeFileExtension(fileName); - if (fileName === noExtension) return fileName; - if (fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Dcts, Extension.Cts])) return noExtension + getJSExtensionForFile(fileName, options); - switch (ending) { - case Ending.Minimal: + if (fileName === noExtension) { + return fileName; + } + + if (fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Dcts, Extension.Cts])) { + return noExtension + getJSExtensionForFile(fileName, options); + } + + switch (allowedEndings[0]) { + case ModuleSpecifierEnding.Minimal: const withoutIndex = removeSuffix(noExtension, "/index"); if (host && withoutIndex !== noExtension && tryGetAnyFileFromPath(host, withoutIndex)) { // Can't remove index if there's a file by the same name as the directory. @@ -1050,12 +1046,23 @@ function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, option return noExtension; } return withoutIndex; - case Ending.Index: + case ModuleSpecifierEnding.Index: return noExtension; - case Ending.JsExtension: + case ModuleSpecifierEnding.JsExtension: return noExtension + getJSExtensionForFile(fileName, options); + case ModuleSpecifierEnding.TsExtension: + // For now, we don't know if this import is going to be type-only, which means we don't + // know if a .d.ts extension is valid, so use no extension or a .js extension + if (isDeclarationFileName(fileName)) { + const extensionlessPriority = allowedEndings.findIndex(e => e === ModuleSpecifierEnding.Minimal || e === ModuleSpecifierEnding.Index); + const jsPriority = allowedEndings.indexOf(ModuleSpecifierEnding.JsExtension); + return extensionlessPriority !== -1 && extensionlessPriority < jsPriority + ? noExtension + : noExtension + getJSExtensionForFile(fileName, options); + } + return fileName; default: - return Debug.assertNever(ending); + return Debug.assertNever(allowedEndings[0]); } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 5cefcfdda324f..ee27160a182e9 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -132,6 +132,7 @@ import { getPropertyArrayElementValue, getPropertyAssignment, getResolvedModule, + getResolveJsonModule, getRootLength, getSetExternalModuleIndicator, getSpellingSuggestion, @@ -215,6 +216,8 @@ import { ModuleResolutionHost, moduleResolutionIsEqualTo, ModuleResolutionKind, + moduleResolutionSupportsPackageJsonExportsAndImports, + moduleResolutionSupportsResolvingTsExtensions, Mutable, Node, NodeArray, @@ -3158,7 +3161,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg for (const node of file.statements) { collectModuleReferences(node, /*inAmbientModule*/ false); } - if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) { + + // `require` has no special meaning in `--moduleResolution bundler` + const shouldProcessRequires = isJavaScriptFile && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Bundler; + if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || shouldProcessRequires) { collectDynamicImportOrRequireCalls(file); } @@ -3220,7 +3226,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg const r = /import|require/g; while (r.exec(file.text) !== null) { // eslint-disable-line no-null/no-null const node = getNodeAtPosition(file, r.lastIndex); - if (isJavaScriptFile && isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { + if (shouldProcessRequires && isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here imports = append(imports, node.arguments[0]); } @@ -4111,10 +4117,11 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } } - if (options.resolveJsonModule) { + if (getResolveJsonModule(options)) { if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 && - getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) { + getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext && + getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Bundler) { createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule"); } // Any emit other than common js, amd, es2015 or esnext is error @@ -4205,6 +4212,21 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_preserveValueImports_can_only_be_used_when_module_is_set_to_es2015_or_later); } + if (options.allowImportingTsExtensions && !(moduleResolutionSupportsResolvingTsExtensions(options) && (options.noEmit || options.emitDeclarationOnly))) { + createOptionValueDiagnostic("allowImportingTsExtensions", Diagnostics.Option_allowImportingTsExtensions_can_only_be_used_when_moduleResolution_is_set_to_bundler_and_either_noEmit_or_emitDeclarationOnly_is_set); + } + + const moduleResolution = getEmitModuleResolutionKind(options); + if (options.resolvePackageJsonExports && !moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) { + createOptionValueDiagnostic("resolvePackageJsonExports", Diagnostics.Option_0_can_only_be_used_when_moduleResolution_is_set_to_node16_nodenext_or_bundler, "resolvePackageJsonExports"); + } + if (options.resolvePackageJsonImports && !moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) { + createOptionValueDiagnostic("resolvePackageJsonImports", Diagnostics.Option_0_can_only_be_used_when_moduleResolution_is_set_to_node16_nodenext_or_bundler, "resolvePackageJsonImports"); + } + if (options.customConditions && !moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) { + createOptionValueDiagnostic("customConditions", Diagnostics.Option_0_can_only_be_used_when_moduleResolution_is_set_to_node16_nodenext_or_bundler, "customConditions"); + } + // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files if (!options.noEmit && !options.suppressOutputPathCheck) { const emitHost = getEmitHost(); @@ -4900,7 +4922,7 @@ export function getResolutionDiagnostic(options: CompilerOptions, { extension }: return getAllowJSCompilerOption(options) || !getStrictOptionValue(options, "noImplicitAny") ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type; } function needResolveJsonModule() { - return options.resolveJsonModule ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used; + return getResolveJsonModule(options) ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used; } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 773d64df907ae..52cd88091726b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6886,6 +6886,7 @@ export enum ModuleResolutionKind { // In turn, we offer both a `NodeNext` moving resolution target, and a `Node16` version-anchored resolution target Node16 = 3, NodeNext = 99, // Not simply `Node16` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`) + Bundler = 100, } export enum ModuleDetectionKind { @@ -6945,6 +6946,7 @@ export type CompilerOptionsValue = string | number | boolean | (string | number) export interface CompilerOptions { /** @internal */ all?: boolean; + allowImportingTsExtensions?: boolean; allowJs?: boolean; /** @internal */ allowNonTsExtensions?: boolean; allowSyntheticDefaultImports?: boolean; @@ -6968,6 +6970,7 @@ export interface CompilerOptions { * @internal */ readonly configFile?: TsConfigSourceFile; + customConditions?: string[]; declaration?: boolean; declarationMap?: boolean; emitDeclarationOnly?: boolean; @@ -7054,6 +7057,8 @@ export interface CompilerOptions { incremental?: boolean; tsBuildInfoFile?: string; removeComments?: boolean; + resolvePackageJsonExports?: boolean; + resolvePackageJsonImports?: boolean; rootDir?: string; rootDirs?: string[]; skipLibCheck?: boolean; @@ -7501,6 +7506,11 @@ export interface ResolvedModule { resolvedFileName: string; /** True if `resolvedFileName` comes from `node_modules`. */ isExternalLibraryImport?: boolean; + /** + * True if the original module reference used a .ts extension to refer directly to a .ts file, + * which should produce an error during checking if emit is enabled. + */ + resolvedUsingTsExtension?: boolean; } /** diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5c65c652db3ef..4f69ae16f98a5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -11,6 +11,7 @@ import { AnyImportOrReExport, AnyImportSyntax, AnyValidImportOrReExport, + append, arrayFrom, ArrayLiteralExpression, ArrayTypeNode, @@ -441,6 +442,7 @@ import { semanticDiagnosticsOptionDeclarations, SetAccessorDeclaration, ShorthandPropertyAssignment, + shouldAllowImportingTsExtension, Signature, SignatureDeclaration, SignatureFlags, @@ -513,6 +515,7 @@ import { TypeReferenceNode, unescapeLeadingUnderscores, UnionOrIntersectionTypeNode, + UserPreferences, ValidImportTypeNode, VariableDeclaration, VariableDeclarationInitializedTo, @@ -7693,6 +7696,10 @@ export function getEmitModuleKind(compilerOptions: {module?: CompilerOptions["mo getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS; } +export function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind) { + return moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext; +} + /** @internal */ export function getEmitModuleResolutionKind(compilerOptions: CompilerOptions) { let moduleResolution = compilerOptions.moduleResolution; @@ -7768,11 +7775,62 @@ export function getESModuleInterop(compilerOptions: CompilerOptions) { /** @internal */ export function getAllowSyntheticDefaultImports(compilerOptions: CompilerOptions) { - const moduleKind = getEmitModuleKind(compilerOptions); - return compilerOptions.allowSyntheticDefaultImports !== undefined - ? compilerOptions.allowSyntheticDefaultImports - : getESModuleInterop(compilerOptions) || - moduleKind === ModuleKind.System; + if (compilerOptions.allowSyntheticDefaultImports !== undefined) { + return compilerOptions.allowSyntheticDefaultImports; + } + return getESModuleInterop(compilerOptions) + || getEmitModuleKind(compilerOptions) === ModuleKind.System + || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler; +} + +/** @internal */ +export function moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution: ModuleResolutionKind): boolean { + return moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext + || moduleResolution === ModuleResolutionKind.Bundler; +} + +/** @internal */ +export function getResolvePackageJsonExports(compilerOptions: CompilerOptions) { + const moduleResolution = getEmitModuleResolutionKind(compilerOptions); + if (!moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) { + return false; + } + if (compilerOptions.resolvePackageJsonExports !== undefined) { + return compilerOptions.resolvePackageJsonExports; + } + switch (moduleResolution) { + case ModuleResolutionKind.Node16: + case ModuleResolutionKind.NodeNext: + case ModuleResolutionKind.Bundler: + return true; + } + return false; +} + +/** @internal */ +export function getResolvePackageJsonImports(compilerOptions: CompilerOptions) { + const moduleResolution = getEmitModuleResolutionKind(compilerOptions); + if (!moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) { + return false; + } + if (compilerOptions.resolvePackageJsonExports !== undefined) { + return compilerOptions.resolvePackageJsonExports; + } + switch (moduleResolution) { + case ModuleResolutionKind.Node16: + case ModuleResolutionKind.NodeNext: + case ModuleResolutionKind.Bundler: + return true; + } + return false; +} + +/** @internal */ +export function getResolveJsonModule(compilerOptions: CompilerOptions) { + if (compilerOptions.resolveJsonModule !== undefined) { + return compilerOptions.resolveJsonModule; + } + return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Bundler; } /** @internal */ @@ -8410,7 +8468,7 @@ export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: Compi export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[][]): readonly string[][]; /** @internal */ export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[][]): readonly string[][] { - if (!options || !options.resolveJsonModule) return supportedExtensions; + if (!options || !getResolveJsonModule(options)) return supportedExtensions; if (supportedExtensions === allSupportedExtensions) return allSupportedExtensionsWithJson; if (supportedExtensions === supportedTSExtensions) return supportedTSExtensionsWithJson; return [...supportedExtensions, [Extension.Json]]; @@ -8430,6 +8488,92 @@ export function hasTSFileExtension(fileName: string): boolean { return some(supportedTSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); } +/** + * @internal + * Corresponds to UserPreferences#importPathEnding + */ +export const enum ModuleSpecifierEnding { + Minimal, + Index, + JsExtension, + TsExtension, +} + +/** @internal */ +export function usesExtensionsOnImports({ imports }: SourceFile, hasExtension: (text: string) => boolean = or(hasJSFileExtension, hasTSFileExtension)): boolean { + return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasExtension(text) : undefined) || false; +} + +/** @internal */ +export function getModuleSpecifierEndingPreference(preference: UserPreferences["importModuleSpecifierEnding"], resolutionMode: ResolutionMode, compilerOptions: CompilerOptions, sourceFile: SourceFile): ModuleSpecifierEnding { + if (preference === "js" || resolutionMode === ModuleKind.ESNext) { + // Extensions are explicitly requested or required. Now choose between .js and .ts. + if (!shouldAllowImportingTsExtension(compilerOptions)) { + return ModuleSpecifierEnding.JsExtension; + } + // `allowImportingTsExtensions` is a strong signal, so use .ts unless the file + // already uses .js extensions and no .ts extensions. + return inferPreference() !== ModuleSpecifierEnding.JsExtension + ? ModuleSpecifierEnding.TsExtension + : ModuleSpecifierEnding.JsExtension; + } + if (preference === "minimal") { + return ModuleSpecifierEnding.Minimal; + } + if (preference === "index") { + return ModuleSpecifierEnding.Index; + } + + // No preference was specified. + // Look at imports and/or requires to guess whether .js, .ts, or extensionless imports are preferred. + // N.B. that `Index` detection is not supported since it would require file system probing to do + // accurately, and more importantly, literally nobody wants `Index` and its existence is a mystery. + if (!shouldAllowImportingTsExtension(compilerOptions)) { + // If .ts imports are not valid, we only need to see one .js import to go with that. + return usesExtensionsOnImports(sourceFile) ? ModuleSpecifierEnding.JsExtension : ModuleSpecifierEnding.Minimal; + } + + return inferPreference(); + + function inferPreference() { + let usesJsExtensions = false; + const specifiers = sourceFile.imports.length ? sourceFile.imports.map(i => i.text) : + isSourceFileJS(sourceFile) ? getRequiresAtTopOfFile(sourceFile).map(r => r.arguments[0].text) : + emptyArray; + for (const specifier of specifiers) { + if (pathIsRelative(specifier)) { + if (hasTSFileExtension(specifier)) { + return ModuleSpecifierEnding.TsExtension; + } + if (hasJSFileExtension(specifier)) { + usesJsExtensions = true; + } + } + } + return usesJsExtensions ? ModuleSpecifierEnding.JsExtension : ModuleSpecifierEnding.Minimal; + } +} + +function getRequiresAtTopOfFile(sourceFile: SourceFile): readonly RequireOrImportCall[] { + let nonRequireStatementCount = 0; + let requires: RequireOrImportCall[] | undefined; + for (const statement of sourceFile.statements) { + if (nonRequireStatementCount > 3) { + break; + } + if (isRequireVariableStatement(statement)) { + requires = concatenate(requires, statement.declarationList.declarations.map(d => d.initializer)); + } + else if (isExpressionStatement(statement) && isRequireCall(statement.expression, /*requireStringLiteralLikeArgument*/ true)) { + requires = append(requires, statement.expression); + } + else { + nonRequireStatementCount++; + } + } + return requires || emptyArray; +} + /** @internal */ export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]) { if (!fileName) return false; diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index ac7c0c40ad3b5..8a2a4c65390d5 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -804,18 +804,6 @@ export class TestState { }); } - private renderMarkers(markers: { text: string, fileName: string, position: number }[]) { - const filesToDisplay = ts.deduplicate(markers.map(m => m.fileName), ts.equateValues); - return filesToDisplay.map(fileName => { - const markersToRender = markers.filter(m => m.fileName === fileName).sort((a, b) => b.position - a.position); - let fileContent = this.tryGetFileContent(fileName) || ""; - for (const marker of markersToRender) { - fileContent = fileContent.slice(0, marker.position) + `\x1b[1;4m/*${marker.text}*/\x1b[0;31m` + fileContent.slice(marker.position); - } - return `// @Filename: ${fileName}\n${fileContent}`; - }).join("\n\n"); - } - private verifyDefinitionTextSpan(defs: ts.DefinitionInfoAndBoundSpan, startMarkerName: string) { const range = this.testData.ranges.find(range => this.markerName(range.marker!) === startMarkerName); @@ -839,6 +827,22 @@ export class TestState { } } + private renderMarkers(markers: { text: string, fileName: string, position: number }[], useTerminalBoldSequence = true) { + const filesToDisplay = ts.deduplicate(markers.map(m => m.fileName), ts.equateValues); + return filesToDisplay.map(fileName => { + const markersToRender = markers.filter(m => m.fileName === fileName).sort((a, b) => b.position - a.position); + let fileContent = this.tryGetFileContent(fileName) || ""; + for (const marker of markersToRender) { + fileContent = fileContent.slice(0, marker.position) + bold(`/*${marker.text}*/`) + fileContent.slice(marker.position); + } + return `// @Filename: ${fileName}\n${fileContent}`; + }).join("\n\n"); + + function bold(text: string) { + return useTerminalBoldSequence ? `\x1b[1;4m${text}\x1b[0;31m` : text; + } + } + public verifyGetEmitOutputForCurrentFile(expected: string): void { const emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { @@ -3188,12 +3192,53 @@ export class TestState { if (!negative && !validBraceCompletion) { this.raiseError(`${position} is not a valid brace completion position for ${openingBrace}`); } - if (negative && validBraceCompletion) { this.raiseError(`${position} is a valid brace completion position for ${openingBrace}`); } } + public baselineAutoImports(markerName: string, preferences?: ts.UserPreferences) { + const marker = this.getMarkerByName(markerName); + const baselineFile = this.getBaselineFileNameForContainingTestFile(`.baseline.md`); + const completionPreferences = { + includeCompletionsForModuleExports: true, + includeCompletionsWithInsertText: true, + allowIncompleteCompletions: true, + includeCompletionsWithSnippetText: true, + ...preferences + }; + + const ext = ts.getAnyExtensionFromPath(this.activeFile.fileName).slice(1); + const lang = ["mts", "cts"].includes(ext) ? "ts" : ext; + let baselineText = codeFence(this.renderMarkers([{ text: "|", fileName: marker.fileName, position: marker.position }], /*useTerminalBoldSequence*/ false), lang) + "\n\n"; + this.goToMarker(marker); + + const completions = this.getCompletionListAtCaret(completionPreferences)!; + + const autoImportCompletions = completions.entries.filter(c => c.hasAction && c.source && c.sortText === ts.Completions.SortText.AutoImportSuggestions); + if (autoImportCompletions.length) { + baselineText += `## From completions\n\n${autoImportCompletions.map(c => `- \`${c.name}\` from \`"${c.source}"\``).join("\n")}\n\n`; + autoImportCompletions.forEach(c => { + const details = this.getCompletionEntryDetails(c.name, c.source, c.data, completionPreferences); + assert(details?.codeActions, `Entry '${c.name}' from "${c.source}" returned no code actions from completion details request`); + assert(details.codeActions.length === 1, `Entry '${c.name}' from "${c.source}" returned more than one code action`); + assert(details.codeActions[0].changes.length === 1, `Entry '${c.name}' from "${c.source}" returned a code action changing more than one file`); + assert(details.codeActions[0].changes[0].fileName === this.activeFile.fileName, `Entry '${c.name}' from "${c.source}" returned a code action changing a different file`); + const changes = details.codeActions[0].changes[0].textChanges; + const completionChange: ts.TextChange = { newText: c.insertText || c.name, span: c.replacementSpan || completions.optionalReplacementSpan || { start: marker.position, length: 0 } }; + const sortedChanges = [...changes, completionChange].sort((a, b) => a.span.start - b.span.start); + let newFileContent = this.activeFile.content; + for (let i = sortedChanges.length - 1; i >= 0; i--) { + newFileContent = newFileContent.substring(0, sortedChanges[i].span.start) + sortedChanges[i].newText + newFileContent.substring(sortedChanges[i].span.start + sortedChanges[i].span.length); + } + baselineText += codeFence(newFileContent, lang) + "\n\n"; + }); + } + + // TODO: do codefixes too + Harness.Baseline.runBaseline(baselineFile, baselineText); + } + public verifyJsxClosingTag(map: { [markerName: string]: ts.JsxClosingTagInfo | undefined }): void { for (const markerName in map) { this.goToMarker(markerName); @@ -4605,10 +4650,10 @@ function rangesOfDiffBetweenTwoStrings(source: string, target: string) { else { ranges.push({ start: index - 1, length: 1 }); } - } - else { + } + else { ranges.push({ start: index - 1, length: 1 }); - } + } }; for (let index = 0; index < Math.max(source.length, target.length); index++) { @@ -4618,10 +4663,10 @@ function rangesOfDiffBetweenTwoStrings(source: string, target: string) { } return ranges; - } +} - // Adds an _ when the source string and the target string have a whitespace difference - function highlightDifferenceBetweenStrings(source: string, target: string) { +// Adds an _ when the source string and the target string have a whitespace difference +function highlightDifferenceBetweenStrings(source: string, target: string) { const ranges = rangesOfDiffBetweenTwoStrings(source, target); let emTarget = target; ranges.forEach((range, index) => { @@ -4633,8 +4678,12 @@ function rangesOfDiffBetweenTwoStrings(source: string, target: string) { range.start + 1 + additionalOffset, range.start + range.length + 1 + additionalOffset ); - const after = emTarget.slice(range.start + range.length + 1 + additionalOffset, emTarget.length); + const after = emTarget.slice(range.start + range.length + 1 + additionalOffset, emTarget.length); emTarget = before + lhs + between + rhs + after; }); return emTarget; - } +} + +function codeFence(code: string, lang?: string) { + return `\`\`\`${lang || ""}\n${code}\n\`\`\``; +} diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index af1044d6fee6b..b71d67b530d8a 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -488,6 +488,10 @@ export class Verify extends VerifyNegatable { this.state.verifyImportFixModuleSpecifiers(marker, moduleSpecifiers, preferences); } + public baselineAutoImports(marker: string, preferences?: ts.UserPreferences) { + this.state.baselineAutoImports(marker, preferences); + } + public navigationBar(json: any, options?: { checkSpans?: boolean }) { this.state.verifyNavigationBar(json, options); } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 2f0c90737549a..1b753b8942dde 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -814,7 +814,8 @@ function getNewImportFixes( const compilerOptions = program.getCompilerOptions(); const moduleSpecifierResolutionHost = createModuleSpecifierResolutionHost(program, host); const getChecker = createGetChecker(program, host); - const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules(getEmitModuleResolutionKind(compilerOptions)); + const moduleResolution = getEmitModuleResolutionKind(compilerOptions); + const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules(moduleResolution); const getModuleSpecifiers = fromCacheOnly ? (moduleSymbol: Symbol) => ({ moduleSpecifiers: moduleSpecifiers.tryGetModuleSpecifiersFromCache(moduleSymbol, sourceFile, moduleSpecifierResolutionHost, preferences), computedWithoutCache: false }) : (moduleSymbol: Symbol, checker: TypeChecker) => moduleSpecifiers.getModuleSpecifiersWithCacheInfo(moduleSymbol, checker, compilerOptions, sourceFile, moduleSpecifierResolutionHost, preferences); diff --git a/src/services/completions.ts b/src/services/completions.ts index 6e02fd1e567a4..c451f7cf29fed 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -269,7 +269,7 @@ import { modifierToFlag, ModuleDeclaration, ModuleReference, - moduleResolutionRespectsExports, + moduleResolutionSupportsPackageJsonExportsAndImports, NamedImportBindings, Node, NodeArray, @@ -548,7 +548,7 @@ const enum KeywordCompletionFilters { const enum GlobalsSearch { Continue, Success, Fail } -interface ModuleSpecifierResolutioContext { +interface ModuleSpecifierResolutionContext { tryResolve: (exportInfo: readonly SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean) => ModuleSpecifierResolutionResult; resolvedAny: () => boolean; skippedAny: () => boolean; @@ -569,7 +569,7 @@ function resolvingModuleSpecifiers( preferences: UserPreferences, isForImportStatementCompletion: boolean, isValidTypeOnlyUseSite: boolean, - cb: (context: ModuleSpecifierResolutioContext) => TReturn, + cb: (context: ModuleSpecifierResolutionContext) => TReturn, ): TReturn { const start = timestamp(); // Under `--moduleResolution nodenext`, we have to resolve module specifiers up front, because @@ -577,7 +577,7 @@ function resolvingModuleSpecifiers( // relative path into node_modules), and we want to filter those completions out entirely. // Import statement completions always need specifier resolution because the module specifier is // part of their `insertText`, not the `codeActions` creating edits away from the cursor. - const needsFullResolution = isForImportStatementCompletion || moduleResolutionRespectsExports(getEmitModuleResolutionKind(program.getCompilerOptions())); + const needsFullResolution = isForImportStatementCompletion || moduleResolutionSupportsPackageJsonExportsAndImports(getEmitModuleResolutionKind(program.getCompilerOptions())); let skippedAny = false; let ambientCount = 0; let resolvedCount = 0; diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index c319ad3b8e92a..18f8e17750e2c 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -49,10 +49,12 @@ import { getEmitModuleResolutionKind, getLeadingCommentRanges, getModeForUsageLocation, + getModuleSpecifierEndingPreference, getOwnKeys, getPackageJsonTypesVersionsPaths, getPathComponents, getReplacementSpanForContextToken, + getResolvePackageJsonExports, getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, getTokenAtPosition, @@ -89,7 +91,8 @@ import { mapDefined, MapLike, ModuleKind, - ModuleResolutionKind, + moduleResolutionUsesNodeModules, + ModuleSpecifierEnding, moduleSpecifiers, Node, normalizePath, @@ -120,6 +123,7 @@ import { StringLiteralLike, StringLiteralType, stripQuotes, + supportedTSImplementationExtensions, Symbol, SyntaxKind, textPart, @@ -525,49 +529,44 @@ function getStringLiteralCompletionsFromModuleNamesWorker(sourceFile: SourceFile const scriptPath = sourceFile.path; const scriptDirectory = getDirectoryPath(scriptPath); + const extensionOptions = getExtensionOptions(compilerOptions, ReferenceKind.ModuleSpecifier, sourceFile, preferences, mode); return isPathRelativeToScript(literalValue) || !compilerOptions.baseUrl && (isRootedDiskPath(literalValue) || isUrl(literalValue)) - ? getCompletionEntriesForRelativeModules(literalValue, scriptDirectory, compilerOptions, host, scriptPath, getIncludeExtensionOption()) - : getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, mode, compilerOptions, host, getIncludeExtensionOption(), typeChecker); - - function getIncludeExtensionOption() { - const mode = isStringLiteralLike(node) ? getModeForUsageLocation(sourceFile, node) : undefined; - return preferences.importModuleSpecifierEnding === "js" || mode === ModuleKind.ESNext ? IncludeExtensionsOption.ModuleSpecifierCompletion : IncludeExtensionsOption.Exclude; - } + ? getCompletionEntriesForRelativeModules(literalValue, scriptDirectory, compilerOptions, host, scriptPath, extensionOptions) + : getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, mode, compilerOptions, host, extensionOptions, typeChecker); } interface ExtensionOptions { - readonly extensions: readonly Extension[]; - readonly includeExtensionsOption: IncludeExtensionsOption; + readonly extensionsToSearch: readonly Extension[]; + readonly referenceKind: ReferenceKind; + readonly importingSourceFile: SourceFile; + readonly endingPreference?: UserPreferences["importModuleSpecifierEnding"]; + readonly resolutionMode?: ResolutionMode; } -function getExtensionOptions(compilerOptions: CompilerOptions, includeExtensionsOption = IncludeExtensionsOption.Exclude): ExtensionOptions { - return { extensions: flatten(getSupportedExtensionsForModuleResolution(compilerOptions)), includeExtensionsOption }; + +function getExtensionOptions(compilerOptions: CompilerOptions, referenceKind: ReferenceKind, importingSourceFile: SourceFile, preferences?: UserPreferences, resolutionMode?: ResolutionMode): ExtensionOptions { + return { + extensionsToSearch: flatten(getSupportedExtensionsForModuleResolution(compilerOptions)), + referenceKind, + importingSourceFile, + endingPreference: preferences?.importModuleSpecifierEnding, + resolutionMode, + }; } -function getCompletionEntriesForRelativeModules(literalValue: string, scriptDirectory: string, compilerOptions: CompilerOptions, host: LanguageServiceHost, scriptPath: Path, includeExtensions: IncludeExtensionsOption) { - const extensionOptions = getExtensionOptions(compilerOptions, includeExtensions); +function getCompletionEntriesForRelativeModules(literalValue: string, scriptDirectory: string, compilerOptions: CompilerOptions, host: LanguageServiceHost, scriptPath: Path, extensionOptions: ExtensionOptions) { if (compilerOptions.rootDirs) { return getCompletionEntriesForDirectoryFragmentWithRootDirs( compilerOptions.rootDirs, literalValue, scriptDirectory, extensionOptions, compilerOptions, host, scriptPath); } else { - return arrayFrom(getCompletionEntriesForDirectoryFragment(literalValue, scriptDirectory, extensionOptions, host, scriptPath).values()); + return arrayFrom(getCompletionEntriesForDirectoryFragment(literalValue, scriptDirectory, extensionOptions, host, /*moduleSpecifierIsRelative*/ false, scriptPath).values()); } } -function isEmitResolutionKindUsingNodeModules(compilerOptions: CompilerOptions): boolean { - return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs || - getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || - getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext; -} - -function isEmitModuleResolutionRespectingExportMaps(compilerOptions: CompilerOptions) { - return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || - getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext; -} - function getSupportedExtensionsForModuleResolution(compilerOptions: CompilerOptions): readonly Extension[][] { const extensions = getSupportedExtensions(compilerOptions); - return isEmitResolutionKindUsingNodeModules(compilerOptions) ? + const moduleResolution = getEmitModuleResolutionKind(compilerOptions); + return moduleResolutionUsesNodeModules(moduleResolution) ? getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, extensions) : extensions; } @@ -595,22 +594,22 @@ function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[] const basePath = compilerOptions.project || host.getCurrentDirectory(); const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase); - return flatMap(baseDirectories, baseDirectory => arrayFrom(getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude).values())); + return flatMap(baseDirectories, baseDirectory => arrayFrom(getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, /*moduleSpecifierIsRelative*/ true, exclude).values())); } -const enum IncludeExtensionsOption { - Exclude, - Include, - ModuleSpecifierCompletion, +const enum ReferenceKind { + Filename, + ModuleSpecifier, } /** * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename. */ function getCompletionEntriesForDirectoryFragment( fragment: string, - scriptPath: string, + scriptDirectory: string, extensionOptions: ExtensionOptions, host: LanguageServiceHost, + moduleSpecifierIsRelative: boolean, exclude?: string, result = createNameAndKindSet() ): NameAndKindSet { @@ -634,23 +633,25 @@ function getCompletionEntriesForDirectoryFragment( fragment = ensureTrailingDirectorySeparator(fragment); - const absolutePath = resolvePath(scriptPath, fragment); + const absolutePath = resolvePath(scriptDirectory, fragment); const baseDirectory = hasTrailingDirectorySeparator(absolutePath) ? absolutePath : getDirectoryPath(absolutePath); - // check for a version redirect - const packageJsonPath = findPackageJson(baseDirectory, host); - if (packageJsonPath) { - const packageJson = readJson(packageJsonPath, host as { readFile: (filename: string) => string | undefined }); - const typesVersions = (packageJson as any).typesVersions; - if (typeof typesVersions === "object") { - const versionPaths = getPackageJsonTypesVersionsPaths(typesVersions)?.paths; - if (versionPaths) { - const packageDirectory = getDirectoryPath(packageJsonPath); - const pathInPackage = absolutePath.slice(ensureTrailingDirectorySeparator(packageDirectory).length); - if (addCompletionEntriesFromPaths(result, pathInPackage, packageDirectory, extensionOptions, host, versionPaths)) { - // A true result means one of the `versionPaths` was matched, which will block relative resolution - // to files and folders from here. All reachable paths given the pattern match are already added. - return result; + if (!moduleSpecifierIsRelative) { + // check for a version redirect + const packageJsonPath = findPackageJson(baseDirectory, host); + if (packageJsonPath) { + const packageJson = readJson(packageJsonPath, host as { readFile: (filename: string) => string | undefined }); + const typesVersions = (packageJson as any).typesVersions; + if (typeof typesVersions === "object") { + const versionPaths = getPackageJsonTypesVersionsPaths(typesVersions)?.paths; + if (versionPaths) { + const packageDirectory = getDirectoryPath(packageJsonPath); + const pathInPackage = absolutePath.slice(ensureTrailingDirectorySeparator(packageDirectory).length); + if (addCompletionEntriesFromPaths(result, pathInPackage, packageDirectory, extensionOptions, host, versionPaths)) { + // A true result means one of the `versionPaths` was matched, which will block relative resolution + // to files and folders from here. All reachable paths given the pattern match are already added. + return result; + } } } } @@ -660,16 +661,16 @@ function getCompletionEntriesForDirectoryFragment( if (!tryDirectoryExists(host, baseDirectory)) return result; // Enumerate the available files if possible - const files = tryReadDirectory(host, baseDirectory, extensionOptions.extensions, /*exclude*/ undefined, /*include*/ ["./*"]); + const files = tryReadDirectory(host, baseDirectory, extensionOptions.extensionsToSearch, /*exclude*/ undefined, /*include*/ ["./*"]); if (files) { for (let filePath of files) { filePath = normalizePath(filePath); - if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) { + if (exclude && comparePaths(filePath, exclude, scriptDirectory, ignoreCase) === Comparison.EqualTo) { continue; } - const { name, extension } = getFilenameWithExtensionOption(getBaseFileName(filePath), host.getCompilationSettings(), extensionOptions.includeExtensionsOption); + const { name, extension } = getFilenameWithExtensionOption(getBaseFileName(filePath), host.getCompilationSettings(), extensionOptions); result.add(nameAndKind(name, ScriptElementKind.scriptElement, extension)); } } @@ -689,17 +690,32 @@ function getCompletionEntriesForDirectoryFragment( return result; } -function getFilenameWithExtensionOption(name: string, compilerOptions: CompilerOptions, includeExtensionsOption: IncludeExtensionsOption): { name: string, extension: Extension | undefined } { - const outputExtension = moduleSpecifiers.tryGetJSExtensionForFile(name, compilerOptions); - if (includeExtensionsOption === IncludeExtensionsOption.Exclude && !fileExtensionIsOneOf(name, [Extension.Json, Extension.Mts, Extension.Cts, Extension.Dmts, Extension.Dcts, Extension.Mjs, Extension.Cjs])) { - return { name: removeFileExtension(name), extension: tryGetExtensionFromPath(name) }; +function getFilenameWithExtensionOption(name: string, compilerOptions: CompilerOptions, extensionOptions: ExtensionOptions): { name: string, extension: Extension | undefined } { + if (extensionOptions.referenceKind === ReferenceKind.Filename) { + return { name, extension: tryGetExtensionFromPath(name) }; } - else if ((fileExtensionIsOneOf(name, [Extension.Mts, Extension.Cts, Extension.Dmts, Extension.Dcts, Extension.Mjs, Extension.Cjs]) || includeExtensionsOption === IncludeExtensionsOption.ModuleSpecifierCompletion) && outputExtension) { - return { name: changeExtension(name, outputExtension), extension: outputExtension }; + + const endingPreference = getModuleSpecifierEndingPreference(extensionOptions.endingPreference, extensionOptions.resolutionMode, compilerOptions, extensionOptions.importingSourceFile); + if (endingPreference === ModuleSpecifierEnding.TsExtension) { + if (fileExtensionIsOneOf(name, supportedTSImplementationExtensions)) { + return { name, extension: tryGetExtensionFromPath(name) }; + } + const outputExtension = moduleSpecifiers.tryGetJSExtensionForFile(name, compilerOptions); + return outputExtension + ? { name: changeExtension(name, outputExtension), extension: outputExtension } + : { name, extension: tryGetExtensionFromPath(name) }; } - else { - return { name, extension: tryGetExtensionFromPath(name) }; + + if ((endingPreference === ModuleSpecifierEnding.Minimal || endingPreference === ModuleSpecifierEnding.Index) && + fileExtensionIsOneOf(name, [Extension.Js, Extension.Jsx, Extension.Ts, Extension.Tsx, Extension.Dts]) + ) { + return { name: removeFileExtension(name), extension: tryGetExtensionFromPath(name) }; } + + const outputExtension = moduleSpecifiers.tryGetJSExtensionForFile(name, compilerOptions); + return outputExtension + ? { name: changeExtension(name, outputExtension), extension: outputExtension } + : { name, extension: tryGetExtensionFromPath(name) }; } /** @returns whether `fragment` was a match for any `paths` (which should indicate whether any other path completions should be offered) */ @@ -786,17 +802,17 @@ function getCompletionEntriesForNonRelativeModules( mode: ResolutionMode, compilerOptions: CompilerOptions, host: LanguageServiceHost, - includeExtensionsOption: IncludeExtensionsOption, + extensionOptions: ExtensionOptions, typeChecker: TypeChecker, ): readonly NameAndKind[] { const { baseUrl, paths } = compilerOptions; const result = createNameAndKindSet(); - const extensionOptions = getExtensionOptions(compilerOptions, includeExtensionsOption); + const moduleResolution = getEmitModuleResolutionKind(compilerOptions); if (baseUrl) { const projectDir = compilerOptions.project || host.getCurrentDirectory(); const absolute = normalizePath(combinePaths(projectDir, baseUrl)); - getCompletionEntriesForDirectoryFragment(fragment, absolute, extensionOptions, host, /*exclude*/ undefined, result); + getCompletionEntriesForDirectoryFragment(fragment, absolute, extensionOptions, host, /*moduleSpecifierIsRelative*/ false, /*exclude*/ undefined, result); if (paths) { addCompletionEntriesFromPaths(result, fragment, absolute, extensionOptions, host, paths); } @@ -809,7 +825,7 @@ function getCompletionEntriesForNonRelativeModules( getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result); - if (isEmitResolutionKindUsingNodeModules(compilerOptions)) { + if (moduleResolutionUsesNodeModules(moduleResolution)) { // If looking for a global package name, don't just include everything in `node_modules` because that includes dependencies' own dependencies. // (But do if we didn't find anything, e.g. 'package.json' missing.) let foundGlobal = false; @@ -826,10 +842,10 @@ function getCompletionEntriesForNonRelativeModules( let ancestorLookup: (directory: string) => void | undefined = ancestor => { const nodeModules = combinePaths(ancestor, "node_modules"); if (tryDirectoryExists(host, nodeModules)) { - getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result); + getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*moduleSpecifierIsRelative*/ false, /*exclude*/ undefined, result); } }; - if (fragmentDirectory && isEmitModuleResolutionRespectingExportMaps(compilerOptions)) { + if (fragmentDirectory && getResolvePackageJsonExports(compilerOptions)) { const nodeModulesDirectoryLookup = ancestorLookup; ancestorLookup = ancestor => { const components = getPathComponents(fragment); @@ -967,13 +983,13 @@ function getModulesForPathsPattern( // done. const includeGlob = normalizedSuffix ? "**/*" + normalizedSuffix : "./*"; - const matches = mapDefined(tryReadDirectory(host, baseDirectory, extensionOptions.extensions, /*exclude*/ undefined, [includeGlob]), match => { + const matches = mapDefined(tryReadDirectory(host, baseDirectory, extensionOptions.extensionsToSearch, /*exclude*/ undefined, [includeGlob]), match => { const trimmedWithPattern = trimPrefixAndSuffix(match); if (trimmedWithPattern) { if (containsSlash(trimmedWithPattern)) { return directoryResult(getPathComponents(removeLeadingDirectorySeparator(trimmedWithPattern))[1]); } - const { name, extension } = getFilenameWithExtensionOption(trimmedWithPattern, host.getCompilationSettings(), extensionOptions.includeExtensionsOption); + const { name, extension } = getFilenameWithExtensionOption(trimmedWithPattern, host.getCompilationSettings(), extensionOptions); return nameAndKind(name, ScriptElementKind.scriptElement, extension); } }); @@ -1030,8 +1046,8 @@ function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: num const [, prefix, kind, toComplete] = match; const scriptPath = getDirectoryPath(sourceFile.path); - const names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, IncludeExtensionsOption.Include), host, sourceFile.path) - : kind === "types" ? getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, getFragmentDirectory(toComplete), getExtensionOptions(compilerOptions)) + const names = kind === "path" ? getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getExtensionOptions(compilerOptions, ReferenceKind.Filename, sourceFile), host, /*moduleSpecifierIsRelative*/ true, sourceFile.path) + : kind === "types" ? getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, getFragmentDirectory(toComplete), getExtensionOptions(compilerOptions, ReferenceKind.ModuleSpecifier, sourceFile)) : Debug.fail(); return addReplacementSpans(toComplete, range.pos + prefix.length, arrayFrom(names.values())); } @@ -1071,7 +1087,7 @@ function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: Com const baseDirectory = combinePaths(directory, typeDirectoryName); const remainingFragment = tryRemoveDirectoryPrefix(fragmentDirectory, packageName, hostGetCanonicalFileName(host)); if (remainingFragment !== undefined) { - getCompletionEntriesForDirectoryFragment(remainingFragment, baseDirectory, extensionOptions, host, /*exclude*/ undefined, result); + getCompletionEntriesForDirectoryFragment(remainingFragment, baseDirectory, extensionOptions, host, /*moduleSpecifierIsRelative*/ false, /*exclude*/ undefined, result); } } } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index ac93d22ba7699..8369ef43d80ba 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2374,6 +2374,7 @@ export function programContainsModules(program: Program): boolean { export function programContainsEsModules(program: Program): boolean { return program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator); } +// TODO: this function is, at best, poorly named. Use sites are pretty suspicious. /** @internal */ export function compilerOptionsIndicateEsModules(compilerOptions: CompilerOptions): boolean { return !!compilerOptions.module || getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 || !!compilerOptions.noEmit; @@ -2408,11 +2409,6 @@ export function getModuleSpecifierResolverHost(program: Program, host: LanguageS }; } -/** @internal */ -export function moduleResolutionRespectsExports(moduleResolution: ModuleResolutionKind): boolean { - return moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext; -} - /** @internal */ export function moduleResolutionUsesNodeModules(moduleResolution: ModuleResolutionKind): boolean { return moduleResolution === ModuleResolutionKind.NodeJs || moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext; diff --git a/src/testRunner/compilerRunner.ts b/src/testRunner/compilerRunner.ts index bad01ecd0bb01..33d01f4c24953 100644 --- a/src/testRunner/compilerRunner.ts +++ b/src/testRunner/compilerRunner.ts @@ -135,8 +135,10 @@ class CompilerTest { "module", "moduleResolution", "moduleDetection", + "allowImportingTsExtensions", "target", "jsx", + "noEmit", "removeComments", "importHelpers", "importHelpers", @@ -161,6 +163,8 @@ class CompilerTest { "useUnknownInCatchVariables", "noUncheckedIndexedAccess", "noPropertyAccessFromIndexSignature", + "resolvePackageJsonExports", + "resolvePackageJsonImports", ]; private fileName: string; private justName: string; diff --git a/src/testRunner/unittests/helpers.ts b/src/testRunner/unittests/helpers.ts index 725fb7c4e60fb..4e5f2046a416a 100644 --- a/src/testRunner/unittests/helpers.ts +++ b/src/testRunner/unittests/helpers.ts @@ -170,4 +170,4 @@ export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: rea export function updateProgramText(files: readonly NamedSourceText[], fileName: string, newProgramText: string) { const file = ts.find(files, f => f.name === fileName)!; file.text = file.text.updateProgram(newProgramText); -} \ No newline at end of file +} diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0af2b39653975..cad75d3083540 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6971,7 +6971,8 @@ declare namespace ts { Classic = 1, NodeJs = 2, Node16 = 3, - NodeNext = 99 + NodeNext = 99, + Bundler = 100 } enum ModuleDetectionKind { /** @@ -7022,6 +7023,7 @@ declare namespace ts { } type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike | PluginImport[] | ProjectReference[] | null | undefined; interface CompilerOptions { + allowImportingTsExtensions?: boolean; allowJs?: boolean; allowSyntheticDefaultImports?: boolean; allowUmdGlobalAccess?: boolean; @@ -7031,6 +7033,7 @@ declare namespace ts { baseUrl?: string; charset?: string; checkJs?: boolean; + customConditions?: string[]; declaration?: boolean; declarationMap?: boolean; emitDeclarationOnly?: boolean; @@ -7095,6 +7098,8 @@ declare namespace ts { incremental?: boolean; tsBuildInfoFile?: string; removeComments?: boolean; + resolvePackageJsonExports?: boolean; + resolvePackageJsonImports?: boolean; rootDir?: string; rootDirs?: string[]; skipLibCheck?: boolean; @@ -7266,6 +7271,11 @@ declare namespace ts { resolvedFileName: string; /** True if `resolvedFileName` comes from `node_modules`. */ isExternalLibraryImport?: boolean; + /** + * True if the original module reference used a .ts extension to refer directly to a .ts file, + * which should produce an error during checking if emit is enabled. + */ + resolvedUsingTsExtension?: boolean; } /** * ResolvedModule with an explicitly provided `extension` property. @@ -8772,6 +8782,7 @@ declare namespace ts { parent: ConstructorDeclaration; name: Identifier; }; + function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind): boolean; function isJSDocOptionalParameter(node: ParameterDeclaration): boolean; function isOptionalDeclaration(declaration: Declaration): boolean; function createUnparsedSourceFile(text: string): UnparsedSource; @@ -9202,8 +9213,11 @@ declare namespace ts { function createTypeReferenceDirectiveResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions, packageJsonInfoCache?: PackageJsonInfoCache): TypeReferenceDirectiveResolutionCache; function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache, mode?: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined; function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ResolutionMode): ResolvedModuleWithFailedLookupLocations; + function bundlerModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; + function moduleResolutionSupportsResolvingTsExtensions(compilerOptions: CompilerOptions): boolean; + function shouldAllowImportingTsExtension(compilerOptions: CompilerOptions, fromFileName?: string): boolean | "" | undefined; interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache, NonRelativeNameResolutionCache, PackageJsonInfoCache { } interface ModeAwareCache { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index eaf5c1e2626fa..c6bb421d196b8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3037,7 +3037,8 @@ declare namespace ts { Classic = 1, NodeJs = 2, Node16 = 3, - NodeNext = 99 + NodeNext = 99, + Bundler = 100 } enum ModuleDetectionKind { /** @@ -3088,6 +3089,7 @@ declare namespace ts { } type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike | PluginImport[] | ProjectReference[] | null | undefined; interface CompilerOptions { + allowImportingTsExtensions?: boolean; allowJs?: boolean; allowSyntheticDefaultImports?: boolean; allowUmdGlobalAccess?: boolean; @@ -3097,6 +3099,7 @@ declare namespace ts { baseUrl?: string; charset?: string; checkJs?: boolean; + customConditions?: string[]; declaration?: boolean; declarationMap?: boolean; emitDeclarationOnly?: boolean; @@ -3161,6 +3164,8 @@ declare namespace ts { incremental?: boolean; tsBuildInfoFile?: string; removeComments?: boolean; + resolvePackageJsonExports?: boolean; + resolvePackageJsonImports?: boolean; rootDir?: string; rootDirs?: string[]; skipLibCheck?: boolean; @@ -3332,6 +3337,11 @@ declare namespace ts { resolvedFileName: string; /** True if `resolvedFileName` comes from `node_modules`. */ isExternalLibraryImport?: boolean; + /** + * True if the original module reference used a .ts extension to refer directly to a .ts file, + * which should produce an error during checking if emit is enabled. + */ + resolvedUsingTsExtension?: boolean; } /** * ResolvedModule with an explicitly provided `extension` property. @@ -4838,6 +4848,7 @@ declare namespace ts { parent: ConstructorDeclaration; name: Identifier; }; + function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind): boolean; function isJSDocOptionalParameter(node: ParameterDeclaration): boolean; function isOptionalDeclaration(declaration: Declaration): boolean; function createUnparsedSourceFile(text: string): UnparsedSource; @@ -5268,8 +5279,11 @@ declare namespace ts { function createTypeReferenceDirectiveResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions, packageJsonInfoCache?: PackageJsonInfoCache): TypeReferenceDirectiveResolutionCache; function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache, mode?: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined; function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ResolutionMode): ResolvedModuleWithFailedLookupLocations; + function bundlerModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; + function moduleResolutionSupportsResolvingTsExtensions(compilerOptions: CompilerOptions): boolean; + function shouldAllowImportingTsExtension(compilerOptions: CompilerOptions, fromFileName?: string): boolean | "" | undefined; interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache, NonRelativeNameResolutionCache, PackageJsonInfoCache { } interface ModeAwareCache { diff --git a/tests/baselines/reference/autoImportAllowTsExtensions1.baseline.md b/tests/baselines/reference/autoImportAllowTsExtensions1.baseline.md new file mode 100644 index 0000000000000..0e3c27ce7e96a --- /dev/null +++ b/tests/baselines/reference/autoImportAllowTsExtensions1.baseline.md @@ -0,0 +1,36 @@ +```ts +// @Filename: /main.ts +/*|*/ +``` + +## From completions + +- `Component` from `"./Component"` +- `fromAtTypesFoo` from `"foo"` +- `fromBar` from `"bar"` +- `fromLocal` from `"./local"` + +```ts +import { Component } from "./Component"; + +Component +``` + +```ts +import { fromAtTypesFoo } from "foo"; + +fromAtTypesFoo +``` + +```ts +import { fromBar } from "bar"; + +fromBar +``` + +```ts +import { fromLocal } from "./local"; + +fromLocal +``` + diff --git a/tests/baselines/reference/autoImportAllowTsExtensions2.baseline.md b/tests/baselines/reference/autoImportAllowTsExtensions2.baseline.md new file mode 100644 index 0000000000000..1117148b1877d --- /dev/null +++ b/tests/baselines/reference/autoImportAllowTsExtensions2.baseline.md @@ -0,0 +1,36 @@ +```ts +// @Filename: /main.ts +/*|*/ +``` + +## From completions + +- `Component` from `"./Component.tsx"` +- `fromAtTypesFoo` from `"foo"` +- `fromBar` from `"bar"` +- `fromLocal` from `"./local.ts"` + +```ts +import { Component } from "./Component.tsx"; + +Component +``` + +```ts +import { fromAtTypesFoo } from "foo"; + +fromAtTypesFoo +``` + +```ts +import { fromBar } from "bar"; + +fromBar +``` + +```ts +import { fromLocal } from "./local.ts"; + +fromLocal +``` + diff --git a/tests/baselines/reference/autoImportAllowTsExtensions3.baseline.md b/tests/baselines/reference/autoImportAllowTsExtensions3.baseline.md new file mode 100644 index 0000000000000..551ff404a6a33 --- /dev/null +++ b/tests/baselines/reference/autoImportAllowTsExtensions3.baseline.md @@ -0,0 +1,23 @@ +```ts +// @Filename: /main.ts +import { Component } from "./Component.tsx"; +/*|*/ +``` + +## From completions + +- `fromDecl` from `"./decl"` +- `fromLocal` from `"./local.ts"` + +```ts +import { Component } from "./Component.tsx"; +import { fromDecl } from "./decl"; +fromDecl +``` + +```ts +import { Component } from "./Component.tsx"; +import { fromLocal } from "./local.ts"; +fromLocal +``` + diff --git a/tests/baselines/reference/autoImportAllowTsExtensions4.baseline.md b/tests/baselines/reference/autoImportAllowTsExtensions4.baseline.md new file mode 100644 index 0000000000000..cdae3c5eaa40b --- /dev/null +++ b/tests/baselines/reference/autoImportAllowTsExtensions4.baseline.md @@ -0,0 +1,22 @@ +```ts +// @Filename: /main.ts +import { Component } from "./local.js"; +/*|*/ +``` + +## From completions + +- `fromDecl` from `"./decl.js"` +- `fromLocal` from `"./local.js"` + +```ts +import { fromDecl } from "./decl.js"; +import { Component } from "./local.js"; +fromDecl +``` + +```ts +import { Component, fromLocal } from "./local.js"; +fromLocal +``` + diff --git a/tests/baselines/reference/bundlerImportESM.js b/tests/baselines/reference/bundlerImportESM.js new file mode 100644 index 0000000000000..efe3cbd491689 --- /dev/null +++ b/tests/baselines/reference/bundlerImportESM.js @@ -0,0 +1,26 @@ +//// [tests/cases/conformance/moduleResolution/bundler/bundlerImportESM.ts] //// + +//// [esm.mts] +export const esm = 0; + +//// [not-actually-cjs.cts] +import { esm } from "./esm.mjs"; + +//// [package.json] +{ "type": "commonjs" } + +//// [still-not-cjs.ts] +import { esm } from "./esm.mjs"; + + +//// [esm.mjs] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.esm = void 0; +exports.esm = 0; +//// [not-actually-cjs.cjs] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [still-not-cjs.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/bundlerImportESM.symbols b/tests/baselines/reference/bundlerImportESM.symbols new file mode 100644 index 0000000000000..de03eed56fdc2 --- /dev/null +++ b/tests/baselines/reference/bundlerImportESM.symbols @@ -0,0 +1,12 @@ +=== /esm.mts === +export const esm = 0; +>esm : Symbol(esm, Decl(esm.mts, 0, 12)) + +=== /not-actually-cjs.cts === +import { esm } from "./esm.mjs"; +>esm : Symbol(esm, Decl(not-actually-cjs.cts, 0, 8)) + +=== /still-not-cjs.ts === +import { esm } from "./esm.mjs"; +>esm : Symbol(esm, Decl(still-not-cjs.ts, 0, 8)) + diff --git a/tests/baselines/reference/bundlerImportESM.types b/tests/baselines/reference/bundlerImportESM.types new file mode 100644 index 0000000000000..3ffcb432c7bff --- /dev/null +++ b/tests/baselines/reference/bundlerImportESM.types @@ -0,0 +1,13 @@ +=== /esm.mts === +export const esm = 0; +>esm : 0 +>0 : 0 + +=== /not-actually-cjs.cts === +import { esm } from "./esm.mjs"; +>esm : 0 + +=== /still-not-cjs.ts === +import { esm } from "./esm.mjs"; +>esm : 0 + diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).errors.txt b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).errors.txt new file mode 100644 index 0000000000000..e679c61f21d2e --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).errors.txt @@ -0,0 +1,103 @@ +error TS5056: Cannot write file 'out/b.js' because it would be overwritten by multiple input files. +error TS5056: Cannot write file 'out/c.js' because it would be overwritten by multiple input files. +error TS6054: File '/project/e.txt' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'. + The file is in the program because: + Root file specified for compilation +/project/main.ts(3,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/project/main.ts(7,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/project/main.ts(8,16): error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './b' instead? +/project/main.ts(11,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/project/main.ts(12,16): error TS5097: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled. +/project/main.ts(12,16): error TS6142: Module './c.tsx' was resolved to '/project/c.tsx', but '--jsx' is not set. +/project/main.ts(16,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/project/types.d.ts(2,16): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. +/project/types.d.ts(3,21): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. + + +!!! error TS5056: Cannot write file 'out/b.js' because it would be overwritten by multiple input files. +!!! error TS5056: Cannot write file 'out/c.js' because it would be overwritten by multiple input files. +!!! error TS6054: File '/project/e.txt' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'. +!!! error TS6054: The file is in the program because: +!!! error TS6054: Root file specified for compilation +==== /project/a.ts (0 errors) ==== + export {}; + +==== /project/b.ts (0 errors) ==== + export {}; + +==== /project/b.js (0 errors) ==== + export {}; + +==== /project/b.d.ts (0 errors) ==== + export {}; + +==== /project/c.ts (0 errors) ==== + export {}; + +==== /project/c.tsx (0 errors) ==== + export {}; + +==== /project/d/index.ts (0 errors) ==== + export {}; + +==== /project/e (0 errors) ==== + WOMP WOMP BINARY DATA + +==== /project/e.ts (0 errors) ==== + export {}; + +==== /project/e.txt (0 errors) ==== + The letter e is for elephant + This poem is not about elephants + It is about the letter e + - Authored by GitHub Copilot, Nov 2022 + +==== /project/e.txt.ts (0 errors) ==== + export {}; + +==== /project/main.ts (7 errors) ==== + import {} from "./a"; + import {} from "./a.js"; + import {} from "./a.ts"; + ~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + + import {} from "./b"; + import {} from "./b.js"; + import {} from "./b.ts"; + ~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + import {} from "./b.d.ts"; + ~~~~~~~~~~ +!!! error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './b' instead? + import type {} from "./b.d.ts"; + + import {} from "./c.ts"; + ~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + import {} from "./c.tsx"; + ~~~~~~~~~ +!!! error TS5097: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled. + ~~~~~~~~~ +!!! error TS6142: Module './c.tsx' was resolved to '/project/c.tsx', but '--jsx' is not set. + + import {} from "./d"; + import {} from "./d/index"; + import {} from "./d/index.ts"; + ~~~~~~~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + + // These should not resolve, but preventing them has + // relatively little utility compared to the cost of + // the filesystem hits. + import {} from "./e"; + import {} from "./e.txt"; + +==== /project/types.d.ts (2 errors) ==== + import {} from "./a.ts"; + import {} from "./a.d.ts"; + ~~~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. + import type {} from "./a.d.ts"; + ~~~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. \ No newline at end of file diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).js b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).js new file mode 100644 index 0000000000000..e6f603d88dc3b --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).js @@ -0,0 +1,82 @@ +//// [tests/cases/conformance/moduleResolution/bundler/bundlerImportTsExtensions.ts] //// + +//// [a.ts] +export {}; + +//// [b.ts] +export {}; + +//// [b.js] +export {}; + +//// [b.d.ts] +export {}; + +//// [c.ts] +export {}; + +//// [c.tsx] +export {}; + +//// [index.ts] +export {}; + +//// [e] +WOMP WOMP BINARY DATA + +//// [e.ts] +export {}; + +//// [e.txt] +The letter e is for elephant +This poem is not about elephants +It is about the letter e +- Authored by GitHub Copilot, Nov 2022 + +//// [e.txt.ts] +export {}; + +//// [main.ts] +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +//// [types.d.ts] +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [e.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [e.txt.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [main.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).symbols b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).symbols new file mode 100644 index 0000000000000..3c1dc17c50c28 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).symbols @@ -0,0 +1,66 @@ +=== /project/a.ts === + +export {}; + +=== /project/b.ts === + +export {}; + +=== /project/b.js === + +export {}; + +=== /project/b.d.ts === + +export {}; + +=== /project/c.ts === + +export {}; + +=== /project/c.tsx === + +export {}; + +=== /project/d/index.ts === + +export {}; + +=== /project/e.ts === + +export {}; + +=== /project/e.txt.ts === + +export {}; + +=== /project/main.ts === + +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +=== /project/types.d.ts === + +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).trace.json b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).trace.json new file mode 100644 index 0000000000000..16bd4a9de2e58 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).trace.json @@ -0,0 +1,101 @@ +[ + "======== Resolving module './a' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.js' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.js' has a '.js' extension - stripping it.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a.js' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.ts' has a '.ts' extension - stripping it.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a.ts' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './b' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.js' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.js' has a '.js' extension - stripping it.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b.js' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.ts' has a '.ts' extension - stripping it.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b.ts' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.d.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.d.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.d.ts' has a '.d.ts' extension - stripping it.", + "File '/project/b.d.ts' exist - use it as a name resolution result.", + "======== Module name './b.d.ts' was successfully resolved to '/project/b.d.ts'. ========", + "======== Resolving module './c.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/c.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/c.ts' has a '.ts' extension - stripping it.", + "File '/project/c.ts' exist - use it as a name resolution result.", + "======== Module name './c.ts' was successfully resolved to '/project/c.ts'. ========", + "======== Resolving module './c.tsx' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/c.tsx', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/c.tsx' has a '.tsx' extension - stripping it.", + "File '/project/c.tsx' exist - use it as a name resolution result.", + "======== Module name './c.tsx' was successfully resolved to '/project/c.tsx'. ========", + "======== Resolving module './d' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/d.ts' does not exist.", + "File '/project/d.tsx' does not exist.", + "File '/project/d.d.ts' does not exist.", + "File '/project/d.js' does not exist.", + "File '/project/d.jsx' does not exist.", + "File '/project/d/package.json' does not exist.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './d/index' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d/index', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d/index' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './d/index.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d/index.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/d/index.ts' has a '.ts' extension - stripping it.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d/index.ts' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './e' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/e', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/e.ts' exist - use it as a name resolution result.", + "======== Module name './e' was successfully resolved to '/project/e.ts'. ========", + "======== Resolving module './e.txt' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/e.txt', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/e.txt.ts' exist - use it as a name resolution result.", + "======== Module name './e.txt' was successfully resolved to '/project/e.txt.ts'. ========", + "======== Resolving module './a.ts' from '/project/types.d.ts'. ========", + "Resolution for module './a.ts' was found in cache from location '/project'.", + "======== Module name './a.ts' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.d.ts' from '/project/types.d.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.d.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.d.ts' has a '.d.ts' extension - stripping it.", + "File '/project/a.d.ts' does not exist.", + "File '/project/a.d.ts.ts' does not exist.", + "File '/project/a.d.ts.tsx' does not exist.", + "File '/project/a.d.ts.d.ts' does not exist.", + "File '/project/a.d.ts.js' does not exist.", + "File '/project/a.d.ts.jsx' does not exist.", + "Directory '/project/a.d.ts' does not exist, skipping all lookups in it.", + "======== Module name './a.d.ts' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).types b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).types new file mode 100644 index 0000000000000..3c1dc17c50c28 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=false).types @@ -0,0 +1,66 @@ +=== /project/a.ts === + +export {}; + +=== /project/b.ts === + +export {}; + +=== /project/b.js === + +export {}; + +=== /project/b.d.ts === + +export {}; + +=== /project/c.ts === + +export {}; + +=== /project/c.tsx === + +export {}; + +=== /project/d/index.ts === + +export {}; + +=== /project/e.ts === + +export {}; + +=== /project/e.txt.ts === + +export {}; + +=== /project/main.ts === + +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +=== /project/types.d.ts === + +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).errors.txt b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).errors.txt new file mode 100644 index 0000000000000..a90647850052e --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).errors.txt @@ -0,0 +1,99 @@ +error TS6054: File '/project/e.txt' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'. + The file is in the program because: + Root file specified for compilation +/project/main.ts(3,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/project/main.ts(7,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/project/main.ts(8,16): error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './b' instead? +/project/main.ts(11,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/project/main.ts(12,16): error TS5097: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled. +/project/main.ts(12,16): error TS6142: Module './c.tsx' was resolved to '/project/c.tsx', but '--jsx' is not set. +/project/main.ts(16,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/project/types.d.ts(2,16): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. +/project/types.d.ts(3,21): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. + + +!!! error TS6054: File '/project/e.txt' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'. +!!! error TS6054: The file is in the program because: +!!! error TS6054: Root file specified for compilation +==== /project/a.ts (0 errors) ==== + export {}; + +==== /project/b.ts (0 errors) ==== + export {}; + +==== /project/b.js (0 errors) ==== + export {}; + +==== /project/b.d.ts (0 errors) ==== + export {}; + +==== /project/c.ts (0 errors) ==== + export {}; + +==== /project/c.tsx (0 errors) ==== + export {}; + +==== /project/d/index.ts (0 errors) ==== + export {}; + +==== /project/e (0 errors) ==== + WOMP WOMP BINARY DATA + +==== /project/e.ts (0 errors) ==== + export {}; + +==== /project/e.txt (0 errors) ==== + The letter e is for elephant + This poem is not about elephants + It is about the letter e + - Authored by GitHub Copilot, Nov 2022 + +==== /project/e.txt.ts (0 errors) ==== + export {}; + +==== /project/main.ts (7 errors) ==== + import {} from "./a"; + import {} from "./a.js"; + import {} from "./a.ts"; + ~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + + import {} from "./b"; + import {} from "./b.js"; + import {} from "./b.ts"; + ~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + import {} from "./b.d.ts"; + ~~~~~~~~~~ +!!! error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './b' instead? + import type {} from "./b.d.ts"; + + import {} from "./c.ts"; + ~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + import {} from "./c.tsx"; + ~~~~~~~~~ +!!! error TS5097: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled. + ~~~~~~~~~ +!!! error TS6142: Module './c.tsx' was resolved to '/project/c.tsx', but '--jsx' is not set. + + import {} from "./d"; + import {} from "./d/index"; + import {} from "./d/index.ts"; + ~~~~~~~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + + // These should not resolve, but preventing them has + // relatively little utility compared to the cost of + // the filesystem hits. + import {} from "./e"; + import {} from "./e.txt"; + +==== /project/types.d.ts (2 errors) ==== + import {} from "./a.ts"; + import {} from "./a.d.ts"; + ~~~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. + import type {} from "./a.d.ts"; + ~~~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. \ No newline at end of file diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).symbols b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).symbols new file mode 100644 index 0000000000000..3c1dc17c50c28 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).symbols @@ -0,0 +1,66 @@ +=== /project/a.ts === + +export {}; + +=== /project/b.ts === + +export {}; + +=== /project/b.js === + +export {}; + +=== /project/b.d.ts === + +export {}; + +=== /project/c.ts === + +export {}; + +=== /project/c.tsx === + +export {}; + +=== /project/d/index.ts === + +export {}; + +=== /project/e.ts === + +export {}; + +=== /project/e.txt.ts === + +export {}; + +=== /project/main.ts === + +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +=== /project/types.d.ts === + +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).trace.json b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).trace.json new file mode 100644 index 0000000000000..16bd4a9de2e58 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).trace.json @@ -0,0 +1,101 @@ +[ + "======== Resolving module './a' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.js' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.js' has a '.js' extension - stripping it.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a.js' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.ts' has a '.ts' extension - stripping it.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a.ts' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './b' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.js' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.js' has a '.js' extension - stripping it.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b.js' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.ts' has a '.ts' extension - stripping it.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b.ts' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.d.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.d.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.d.ts' has a '.d.ts' extension - stripping it.", + "File '/project/b.d.ts' exist - use it as a name resolution result.", + "======== Module name './b.d.ts' was successfully resolved to '/project/b.d.ts'. ========", + "======== Resolving module './c.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/c.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/c.ts' has a '.ts' extension - stripping it.", + "File '/project/c.ts' exist - use it as a name resolution result.", + "======== Module name './c.ts' was successfully resolved to '/project/c.ts'. ========", + "======== Resolving module './c.tsx' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/c.tsx', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/c.tsx' has a '.tsx' extension - stripping it.", + "File '/project/c.tsx' exist - use it as a name resolution result.", + "======== Module name './c.tsx' was successfully resolved to '/project/c.tsx'. ========", + "======== Resolving module './d' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/d.ts' does not exist.", + "File '/project/d.tsx' does not exist.", + "File '/project/d.d.ts' does not exist.", + "File '/project/d.js' does not exist.", + "File '/project/d.jsx' does not exist.", + "File '/project/d/package.json' does not exist.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './d/index' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d/index', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d/index' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './d/index.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d/index.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/d/index.ts' has a '.ts' extension - stripping it.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d/index.ts' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './e' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/e', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/e.ts' exist - use it as a name resolution result.", + "======== Module name './e' was successfully resolved to '/project/e.ts'. ========", + "======== Resolving module './e.txt' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/e.txt', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/e.txt.ts' exist - use it as a name resolution result.", + "======== Module name './e.txt' was successfully resolved to '/project/e.txt.ts'. ========", + "======== Resolving module './a.ts' from '/project/types.d.ts'. ========", + "Resolution for module './a.ts' was found in cache from location '/project'.", + "======== Module name './a.ts' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.d.ts' from '/project/types.d.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.d.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.d.ts' has a '.d.ts' extension - stripping it.", + "File '/project/a.d.ts' does not exist.", + "File '/project/a.d.ts.ts' does not exist.", + "File '/project/a.d.ts.tsx' does not exist.", + "File '/project/a.d.ts.d.ts' does not exist.", + "File '/project/a.d.ts.js' does not exist.", + "File '/project/a.d.ts.jsx' does not exist.", + "Directory '/project/a.d.ts' does not exist, skipping all lookups in it.", + "======== Module name './a.d.ts' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).types b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).types new file mode 100644 index 0000000000000..3c1dc17c50c28 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=false,noemit=true).types @@ -0,0 +1,66 @@ +=== /project/a.ts === + +export {}; + +=== /project/b.ts === + +export {}; + +=== /project/b.js === + +export {}; + +=== /project/b.d.ts === + +export {}; + +=== /project/c.ts === + +export {}; + +=== /project/c.tsx === + +export {}; + +=== /project/d/index.ts === + +export {}; + +=== /project/e.ts === + +export {}; + +=== /project/e.txt.ts === + +export {}; + +=== /project/main.ts === + +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +=== /project/types.d.ts === + +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).errors.txt b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).errors.txt new file mode 100644 index 0000000000000..683dac372525f --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).errors.txt @@ -0,0 +1,90 @@ +error TS5056: Cannot write file 'out/b.js' because it would be overwritten by multiple input files. +error TS5056: Cannot write file 'out/c.js' because it would be overwritten by multiple input files. +error TS5096: Option 'allowImportingTsExtensions' can only be used when 'moduleResolution' is set to 'bundler' and either 'noEmit' or 'emitDeclarationOnly' is set. +error TS6054: File '/project/e.txt' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'. + The file is in the program because: + Root file specified for compilation +/project/main.ts(8,16): error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './b' instead? +/project/main.ts(12,16): error TS6142: Module './c.tsx' was resolved to '/project/c.tsx', but '--jsx' is not set. +/project/types.d.ts(2,16): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. +/project/types.d.ts(3,21): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. + + +!!! error TS5056: Cannot write file 'out/b.js' because it would be overwritten by multiple input files. +!!! error TS5056: Cannot write file 'out/c.js' because it would be overwritten by multiple input files. +!!! error TS5096: Option 'allowImportingTsExtensions' can only be used when 'moduleResolution' is set to 'bundler' and either 'noEmit' or 'emitDeclarationOnly' is set. +!!! error TS6054: File '/project/e.txt' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'. +!!! error TS6054: The file is in the program because: +!!! error TS6054: Root file specified for compilation +==== /project/a.ts (0 errors) ==== + export {}; + +==== /project/b.ts (0 errors) ==== + export {}; + +==== /project/b.js (0 errors) ==== + export {}; + +==== /project/b.d.ts (0 errors) ==== + export {}; + +==== /project/c.ts (0 errors) ==== + export {}; + +==== /project/c.tsx (0 errors) ==== + export {}; + +==== /project/d/index.ts (0 errors) ==== + export {}; + +==== /project/e (0 errors) ==== + WOMP WOMP BINARY DATA + +==== /project/e.ts (0 errors) ==== + export {}; + +==== /project/e.txt (0 errors) ==== + The letter e is for elephant + This poem is not about elephants + It is about the letter e + - Authored by GitHub Copilot, Nov 2022 + +==== /project/e.txt.ts (0 errors) ==== + export {}; + +==== /project/main.ts (2 errors) ==== + import {} from "./a"; + import {} from "./a.js"; + import {} from "./a.ts"; + + import {} from "./b"; + import {} from "./b.js"; + import {} from "./b.ts"; + import {} from "./b.d.ts"; + ~~~~~~~~~~ +!!! error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './b' instead? + import type {} from "./b.d.ts"; + + import {} from "./c.ts"; + import {} from "./c.tsx"; + ~~~~~~~~~ +!!! error TS6142: Module './c.tsx' was resolved to '/project/c.tsx', but '--jsx' is not set. + + import {} from "./d"; + import {} from "./d/index"; + import {} from "./d/index.ts"; + + // These should not resolve, but preventing them has + // relatively little utility compared to the cost of + // the filesystem hits. + import {} from "./e"; + import {} from "./e.txt"; + +==== /project/types.d.ts (2 errors) ==== + import {} from "./a.ts"; + import {} from "./a.d.ts"; + ~~~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. + import type {} from "./a.d.ts"; + ~~~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. \ No newline at end of file diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).js b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).js new file mode 100644 index 0000000000000..e6f603d88dc3b --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).js @@ -0,0 +1,82 @@ +//// [tests/cases/conformance/moduleResolution/bundler/bundlerImportTsExtensions.ts] //// + +//// [a.ts] +export {}; + +//// [b.ts] +export {}; + +//// [b.js] +export {}; + +//// [b.d.ts] +export {}; + +//// [c.ts] +export {}; + +//// [c.tsx] +export {}; + +//// [index.ts] +export {}; + +//// [e] +WOMP WOMP BINARY DATA + +//// [e.ts] +export {}; + +//// [e.txt] +The letter e is for elephant +This poem is not about elephants +It is about the letter e +- Authored by GitHub Copilot, Nov 2022 + +//// [e.txt.ts] +export {}; + +//// [main.ts] +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +//// [types.d.ts] +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [e.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [e.txt.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [main.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).symbols b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).symbols new file mode 100644 index 0000000000000..3c1dc17c50c28 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).symbols @@ -0,0 +1,66 @@ +=== /project/a.ts === + +export {}; + +=== /project/b.ts === + +export {}; + +=== /project/b.js === + +export {}; + +=== /project/b.d.ts === + +export {}; + +=== /project/c.ts === + +export {}; + +=== /project/c.tsx === + +export {}; + +=== /project/d/index.ts === + +export {}; + +=== /project/e.ts === + +export {}; + +=== /project/e.txt.ts === + +export {}; + +=== /project/main.ts === + +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +=== /project/types.d.ts === + +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).trace.json b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).trace.json new file mode 100644 index 0000000000000..16bd4a9de2e58 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).trace.json @@ -0,0 +1,101 @@ +[ + "======== Resolving module './a' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.js' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.js' has a '.js' extension - stripping it.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a.js' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.ts' has a '.ts' extension - stripping it.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a.ts' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './b' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.js' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.js' has a '.js' extension - stripping it.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b.js' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.ts' has a '.ts' extension - stripping it.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b.ts' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.d.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.d.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.d.ts' has a '.d.ts' extension - stripping it.", + "File '/project/b.d.ts' exist - use it as a name resolution result.", + "======== Module name './b.d.ts' was successfully resolved to '/project/b.d.ts'. ========", + "======== Resolving module './c.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/c.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/c.ts' has a '.ts' extension - stripping it.", + "File '/project/c.ts' exist - use it as a name resolution result.", + "======== Module name './c.ts' was successfully resolved to '/project/c.ts'. ========", + "======== Resolving module './c.tsx' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/c.tsx', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/c.tsx' has a '.tsx' extension - stripping it.", + "File '/project/c.tsx' exist - use it as a name resolution result.", + "======== Module name './c.tsx' was successfully resolved to '/project/c.tsx'. ========", + "======== Resolving module './d' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/d.ts' does not exist.", + "File '/project/d.tsx' does not exist.", + "File '/project/d.d.ts' does not exist.", + "File '/project/d.js' does not exist.", + "File '/project/d.jsx' does not exist.", + "File '/project/d/package.json' does not exist.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './d/index' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d/index', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d/index' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './d/index.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d/index.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/d/index.ts' has a '.ts' extension - stripping it.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d/index.ts' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './e' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/e', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/e.ts' exist - use it as a name resolution result.", + "======== Module name './e' was successfully resolved to '/project/e.ts'. ========", + "======== Resolving module './e.txt' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/e.txt', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/e.txt.ts' exist - use it as a name resolution result.", + "======== Module name './e.txt' was successfully resolved to '/project/e.txt.ts'. ========", + "======== Resolving module './a.ts' from '/project/types.d.ts'. ========", + "Resolution for module './a.ts' was found in cache from location '/project'.", + "======== Module name './a.ts' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.d.ts' from '/project/types.d.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.d.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.d.ts' has a '.d.ts' extension - stripping it.", + "File '/project/a.d.ts' does not exist.", + "File '/project/a.d.ts.ts' does not exist.", + "File '/project/a.d.ts.tsx' does not exist.", + "File '/project/a.d.ts.d.ts' does not exist.", + "File '/project/a.d.ts.js' does not exist.", + "File '/project/a.d.ts.jsx' does not exist.", + "Directory '/project/a.d.ts' does not exist, skipping all lookups in it.", + "======== Module name './a.d.ts' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).types b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).types new file mode 100644 index 0000000000000..3c1dc17c50c28 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=false).types @@ -0,0 +1,66 @@ +=== /project/a.ts === + +export {}; + +=== /project/b.ts === + +export {}; + +=== /project/b.js === + +export {}; + +=== /project/b.d.ts === + +export {}; + +=== /project/c.ts === + +export {}; + +=== /project/c.tsx === + +export {}; + +=== /project/d/index.ts === + +export {}; + +=== /project/e.ts === + +export {}; + +=== /project/e.txt.ts === + +export {}; + +=== /project/main.ts === + +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +=== /project/types.d.ts === + +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).errors.txt b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).errors.txt new file mode 100644 index 0000000000000..394208e16ad02 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).errors.txt @@ -0,0 +1,84 @@ +error TS6054: File '/project/e.txt' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'. + The file is in the program because: + Root file specified for compilation +/project/main.ts(8,16): error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './b' instead? +/project/main.ts(12,16): error TS6142: Module './c.tsx' was resolved to '/project/c.tsx', but '--jsx' is not set. +/project/types.d.ts(2,16): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. +/project/types.d.ts(3,21): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. + + +!!! error TS6054: File '/project/e.txt' has an unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.cts', '.d.cts', '.cjs', '.mts', '.d.mts', '.mjs'. +!!! error TS6054: The file is in the program because: +!!! error TS6054: Root file specified for compilation +==== /project/a.ts (0 errors) ==== + export {}; + +==== /project/b.ts (0 errors) ==== + export {}; + +==== /project/b.js (0 errors) ==== + export {}; + +==== /project/b.d.ts (0 errors) ==== + export {}; + +==== /project/c.ts (0 errors) ==== + export {}; + +==== /project/c.tsx (0 errors) ==== + export {}; + +==== /project/d/index.ts (0 errors) ==== + export {}; + +==== /project/e (0 errors) ==== + WOMP WOMP BINARY DATA + +==== /project/e.ts (0 errors) ==== + export {}; + +==== /project/e.txt (0 errors) ==== + The letter e is for elephant + This poem is not about elephants + It is about the letter e + - Authored by GitHub Copilot, Nov 2022 + +==== /project/e.txt.ts (0 errors) ==== + export {}; + +==== /project/main.ts (2 errors) ==== + import {} from "./a"; + import {} from "./a.js"; + import {} from "./a.ts"; + + import {} from "./b"; + import {} from "./b.js"; + import {} from "./b.ts"; + import {} from "./b.d.ts"; + ~~~~~~~~~~ +!!! error TS2846: A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file './b' instead? + import type {} from "./b.d.ts"; + + import {} from "./c.ts"; + import {} from "./c.tsx"; + ~~~~~~~~~ +!!! error TS6142: Module './c.tsx' was resolved to '/project/c.tsx', but '--jsx' is not set. + + import {} from "./d"; + import {} from "./d/index"; + import {} from "./d/index.ts"; + + // These should not resolve, but preventing them has + // relatively little utility compared to the cost of + // the filesystem hits. + import {} from "./e"; + import {} from "./e.txt"; + +==== /project/types.d.ts (2 errors) ==== + import {} from "./a.ts"; + import {} from "./a.d.ts"; + ~~~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. + import type {} from "./a.d.ts"; + ~~~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './a' instead. \ No newline at end of file diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).symbols b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).symbols new file mode 100644 index 0000000000000..3c1dc17c50c28 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).symbols @@ -0,0 +1,66 @@ +=== /project/a.ts === + +export {}; + +=== /project/b.ts === + +export {}; + +=== /project/b.js === + +export {}; + +=== /project/b.d.ts === + +export {}; + +=== /project/c.ts === + +export {}; + +=== /project/c.tsx === + +export {}; + +=== /project/d/index.ts === + +export {}; + +=== /project/e.ts === + +export {}; + +=== /project/e.txt.ts === + +export {}; + +=== /project/main.ts === + +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +=== /project/types.d.ts === + +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).trace.json b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).trace.json new file mode 100644 index 0000000000000..16bd4a9de2e58 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).trace.json @@ -0,0 +1,101 @@ +[ + "======== Resolving module './a' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.js' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.js' has a '.js' extension - stripping it.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a.js' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.ts' has a '.ts' extension - stripping it.", + "File '/project/a.ts' exist - use it as a name resolution result.", + "======== Module name './a.ts' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './b' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.js' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.js' has a '.js' extension - stripping it.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b.js' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.ts' has a '.ts' extension - stripping it.", + "File '/project/b.ts' exist - use it as a name resolution result.", + "======== Module name './b.ts' was successfully resolved to '/project/b.ts'. ========", + "======== Resolving module './b.d.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/b.d.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/b.d.ts' has a '.d.ts' extension - stripping it.", + "File '/project/b.d.ts' exist - use it as a name resolution result.", + "======== Module name './b.d.ts' was successfully resolved to '/project/b.d.ts'. ========", + "======== Resolving module './c.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/c.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/c.ts' has a '.ts' extension - stripping it.", + "File '/project/c.ts' exist - use it as a name resolution result.", + "======== Module name './c.ts' was successfully resolved to '/project/c.ts'. ========", + "======== Resolving module './c.tsx' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/c.tsx', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/c.tsx' has a '.tsx' extension - stripping it.", + "File '/project/c.tsx' exist - use it as a name resolution result.", + "======== Module name './c.tsx' was successfully resolved to '/project/c.tsx'. ========", + "======== Resolving module './d' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/d.ts' does not exist.", + "File '/project/d.tsx' does not exist.", + "File '/project/d.d.ts' does not exist.", + "File '/project/d.js' does not exist.", + "File '/project/d.jsx' does not exist.", + "File '/project/d/package.json' does not exist.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './d/index' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d/index', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d/index' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './d/index.ts' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/d/index.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/d/index.ts' has a '.ts' extension - stripping it.", + "File '/project/d/index.ts' exist - use it as a name resolution result.", + "======== Module name './d/index.ts' was successfully resolved to '/project/d/index.ts'. ========", + "======== Resolving module './e' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/e', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/e.ts' exist - use it as a name resolution result.", + "======== Module name './e' was successfully resolved to '/project/e.ts'. ========", + "======== Resolving module './e.txt' from '/project/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/e.txt', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/project/e.txt.ts' exist - use it as a name resolution result.", + "======== Module name './e.txt' was successfully resolved to '/project/e.txt.ts'. ========", + "======== Resolving module './a.ts' from '/project/types.d.ts'. ========", + "Resolution for module './a.ts' was found in cache from location '/project'.", + "======== Module name './a.ts' was successfully resolved to '/project/a.ts'. ========", + "======== Resolving module './a.d.ts' from '/project/types.d.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/project/a.d.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/project/a.d.ts' has a '.d.ts' extension - stripping it.", + "File '/project/a.d.ts' does not exist.", + "File '/project/a.d.ts.ts' does not exist.", + "File '/project/a.d.ts.tsx' does not exist.", + "File '/project/a.d.ts.d.ts' does not exist.", + "File '/project/a.d.ts.js' does not exist.", + "File '/project/a.d.ts.jsx' does not exist.", + "Directory '/project/a.d.ts' does not exist, skipping all lookups in it.", + "======== Module name './a.d.ts' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).types b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).types new file mode 100644 index 0000000000000..3c1dc17c50c28 --- /dev/null +++ b/tests/baselines/reference/bundlerImportTsExtensions(allowimportingtsextensions=true,noemit=true).types @@ -0,0 +1,66 @@ +=== /project/a.ts === + +export {}; + +=== /project/b.ts === + +export {}; + +=== /project/b.js === + +export {}; + +=== /project/b.d.ts === + +export {}; + +=== /project/c.ts === + +export {}; + +=== /project/c.tsx === + +export {}; + +=== /project/d/index.ts === + +export {}; + +=== /project/e.ts === + +export {}; + +=== /project/e.txt.ts === + +export {}; + +=== /project/main.ts === + +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +=== /project/types.d.ts === + +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; diff --git a/tests/baselines/reference/bundlerNodeModules1.errors.txt b/tests/baselines/reference/bundlerNodeModules1.errors.txt new file mode 100644 index 0000000000000..69921a8ce1425 --- /dev/null +++ b/tests/baselines/reference/bundlerNodeModules1.errors.txt @@ -0,0 +1,59 @@ +error TS6504: File '/node_modules/dual/index.cjs' is a JavaScript file. Did you mean to enable the 'allowJs' option? + The file is in the program because: + Root file specified for compilation +error TS6504: File '/node_modules/dual/index.js' is a JavaScript file. Did you mean to enable the 'allowJs' option? + The file is in the program because: + Root file specified for compilation +/main.cts(1,15): error TS2305: Module '"dual"' has no exported member 'cjs'. +/main.mts(1,15): error TS2305: Module '"dual"' has no exported member 'cjs'. +/main.ts(1,15): error TS2305: Module '"dual"' has no exported member 'cjs'. + + +!!! error TS6504: File '/node_modules/dual/index.cjs' is a JavaScript file. Did you mean to enable the 'allowJs' option? +!!! error TS6504: The file is in the program because: +!!! error TS6504: Root file specified for compilation +!!! error TS6504: File '/node_modules/dual/index.js' is a JavaScript file. Did you mean to enable the 'allowJs' option? +!!! error TS6504: The file is in the program because: +!!! error TS6504: Root file specified for compilation +==== /node_modules/dual/package.json (0 errors) ==== + { + "name": "dual", + "version": "1.0.0", + "type": "module", + "main": "index.cjs", + "types": "index.d.cts", + "exports": { + ".": { + "import": "./index.js", + "require": "./index.cjs" + } + } + } + +==== /node_modules/dual/index.js (0 errors) ==== + export const esm = 0; + +==== /node_modules/dual/index.d.ts (0 errors) ==== + export const esm: number; + +==== /node_modules/dual/index.cjs (0 errors) ==== + exports.cjs = 0; + +==== /node_modules/dual/index.d.cts (0 errors) ==== + export const cjs: number; + +==== /main.ts (1 errors) ==== + import { esm, cjs } from "dual"; + ~~~ +!!! error TS2305: Module '"dual"' has no exported member 'cjs'. + +==== /main.mts (1 errors) ==== + import { esm, cjs } from "dual"; + ~~~ +!!! error TS2305: Module '"dual"' has no exported member 'cjs'. + +==== /main.cts (1 errors) ==== + import { esm, cjs } from "dual"; + ~~~ +!!! error TS2305: Module '"dual"' has no exported member 'cjs'. + \ No newline at end of file diff --git a/tests/baselines/reference/bundlerNodeModules1.js b/tests/baselines/reference/bundlerNodeModules1.js new file mode 100644 index 0000000000000..8567c3f9b4561 --- /dev/null +++ b/tests/baselines/reference/bundlerNodeModules1.js @@ -0,0 +1,48 @@ +//// [tests/cases/conformance/moduleResolution/bundler/bundlerNodeModules1.ts] //// + +//// [package.json] +{ + "name": "dual", + "version": "1.0.0", + "type": "module", + "main": "index.cjs", + "types": "index.d.cts", + "exports": { + ".": { + "import": "./index.js", + "require": "./index.cjs" + } + } +} + +//// [index.js] +export const esm = 0; + +//// [index.d.ts] +export const esm: number; + +//// [index.cjs] +exports.cjs = 0; + +//// [index.d.cts] +export const cjs: number; + +//// [main.ts] +import { esm, cjs } from "dual"; + +//// [main.mts] +import { esm, cjs } from "dual"; + +//// [main.cts] +import { esm, cjs } from "dual"; + + +//// [main.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [main.mjs] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [main.cjs] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/bundlerNodeModules1.symbols b/tests/baselines/reference/bundlerNodeModules1.symbols new file mode 100644 index 0000000000000..d19c2e18f2c4d --- /dev/null +++ b/tests/baselines/reference/bundlerNodeModules1.symbols @@ -0,0 +1,23 @@ +=== /node_modules/dual/index.d.ts === +export const esm: number; +>esm : Symbol(esm, Decl(index.d.ts, 0, 12)) + +=== /node_modules/dual/index.d.cts === +export const cjs: number; +>cjs : Symbol(cjs, Decl(index.d.cts, 0, 12)) + +=== /main.ts === +import { esm, cjs } from "dual"; +>esm : Symbol(esm, Decl(main.ts, 0, 8)) +>cjs : Symbol(cjs, Decl(main.ts, 0, 13)) + +=== /main.mts === +import { esm, cjs } from "dual"; +>esm : Symbol(esm, Decl(main.mts, 0, 8)) +>cjs : Symbol(cjs, Decl(main.mts, 0, 13)) + +=== /main.cts === +import { esm, cjs } from "dual"; +>esm : Symbol(esm, Decl(main.cts, 0, 8)) +>cjs : Symbol(cjs, Decl(main.cts, 0, 13)) + diff --git a/tests/baselines/reference/bundlerNodeModules1.trace.json b/tests/baselines/reference/bundlerNodeModules1.trace.json new file mode 100644 index 0000000000000..d1f74dccd4b1a --- /dev/null +++ b/tests/baselines/reference/bundlerNodeModules1.trace.json @@ -0,0 +1,21 @@ +[ + "======== Resolving module 'dual' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "File '/package.json' does not exist.", + "Loading module 'dual' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.", + "Found 'package.json' at '/node_modules/dual/package.json'.", + "Matched 'exports' condition 'import'.", + "Using 'exports' subpath '.' with target './index.js'.", + "File name '/node_modules/dual/index.js' has a '.js' extension - stripping it.", + "File '/node_modules/dual/index.ts' does not exist.", + "File '/node_modules/dual/index.tsx' does not exist.", + "File '/node_modules/dual/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/dual/index.d.ts', result '/node_modules/dual/index.d.ts'.", + "======== Module name 'dual' was successfully resolved to '/node_modules/dual/index.d.ts' with Package ID 'dual/index.d.ts@1.0.0'. ========", + "======== Resolving module 'dual' from '/main.mts'. ========", + "Resolution for module 'dual' was found in cache from location '/'.", + "======== Module name 'dual' was successfully resolved to '/node_modules/dual/index.d.ts' with Package ID 'dual/index.d.ts@1.0.0'. ========", + "======== Resolving module 'dual' from '/main.cts'. ========", + "Resolution for module 'dual' was found in cache from location '/'.", + "======== Module name 'dual' was successfully resolved to '/node_modules/dual/index.d.ts' with Package ID 'dual/index.d.ts@1.0.0'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/bundlerNodeModules1.types b/tests/baselines/reference/bundlerNodeModules1.types new file mode 100644 index 0000000000000..038aac71d8928 --- /dev/null +++ b/tests/baselines/reference/bundlerNodeModules1.types @@ -0,0 +1,23 @@ +=== /node_modules/dual/index.d.ts === +export const esm: number; +>esm : number + +=== /node_modules/dual/index.d.cts === +export const cjs: number; +>cjs : number + +=== /main.ts === +import { esm, cjs } from "dual"; +>esm : number +>cjs : any + +=== /main.mts === +import { esm, cjs } from "dual"; +>esm : number +>cjs : any + +=== /main.cts === +import { esm, cjs } from "dual"; +>esm : number +>cjs : any + diff --git a/tests/baselines/reference/bundlerRelative1.errors.txt b/tests/baselines/reference/bundlerRelative1.errors.txt new file mode 100644 index 0000000000000..738eafa19304f --- /dev/null +++ b/tests/baselines/reference/bundlerRelative1.errors.txt @@ -0,0 +1,39 @@ +/main.ts(4,16): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. +/main.ts(7,16): error TS2307: Cannot find module './redirect/index' or its corresponding type declarations. + + +==== /dir/index.ts (0 errors) ==== + export const x = 0; + +==== /redirect/package.json (0 errors) ==== + { "main": "../foo" } + +==== /foo/index.ts (0 errors) ==== + export const y = 0; + +==== /types/esm.d.ts (0 errors) ==== + declare const _: string; + export default _; + +==== /types/cjs.d.ts (0 errors) ==== + declare const _: string; + export = _; + +==== /main.ts (2 errors) ==== + import { x } from "./dir"; + import {} from "./dir/index"; + import {} from "./dir/index.js"; + import {} from "./dir/index.ts"; + ~~~~~~~~~~~~~~~~ +!!! error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled. + + import { y } from "./redirect"; + import {} from "./redirect/index"; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './redirect/index' or its corresponding type declarations. + + import a from "./types/esm"; + import * as esm from "./types/esm"; + import b from "./types/cjs"; + import * as cjs from "./types/cjs"; + \ No newline at end of file diff --git a/tests/baselines/reference/bundlerRelative1.js b/tests/baselines/reference/bundlerRelative1.js new file mode 100644 index 0000000000000..9238cc0f8ef3b --- /dev/null +++ b/tests/baselines/reference/bundlerRelative1.js @@ -0,0 +1,47 @@ +//// [tests/cases/conformance/moduleResolution/bundler/bundlerRelative1.ts] //// + +//// [index.ts] +export const x = 0; + +//// [package.json] +{ "main": "../foo" } + +//// [index.ts] +export const y = 0; + +//// [esm.d.ts] +declare const _: string; +export default _; + +//// [cjs.d.ts] +declare const _: string; +export = _; + +//// [main.ts] +import { x } from "./dir"; +import {} from "./dir/index"; +import {} from "./dir/index.js"; +import {} from "./dir/index.ts"; + +import { y } from "./redirect"; +import {} from "./redirect/index"; + +import a from "./types/esm"; +import * as esm from "./types/esm"; +import b from "./types/cjs"; +import * as cjs from "./types/cjs"; + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.x = void 0; +exports.x = 0; +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.y = void 0; +exports.y = 0; +//// [main.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/bundlerRelative1.symbols b/tests/baselines/reference/bundlerRelative1.symbols new file mode 100644 index 0000000000000..4bbdf732a77c6 --- /dev/null +++ b/tests/baselines/reference/bundlerRelative1.symbols @@ -0,0 +1,47 @@ +=== /dir/index.ts === +export const x = 0; +>x : Symbol(x, Decl(index.ts, 0, 12)) + +=== /foo/index.ts === +export const y = 0; +>y : Symbol(y, Decl(index.ts, 0, 12)) + +=== /types/esm.d.ts === +declare const _: string; +>_ : Symbol(_, Decl(esm.d.ts, 0, 13)) + +export default _; +>_ : Symbol(_, Decl(esm.d.ts, 0, 13)) + +=== /types/cjs.d.ts === +declare const _: string; +>_ : Symbol(_, Decl(cjs.d.ts, 0, 13)) + +export = _; +>_ : Symbol(_, Decl(cjs.d.ts, 0, 13)) + +=== /main.ts === +import { x } from "./dir"; +>x : Symbol(x, Decl(main.ts, 0, 8)) + +import {} from "./dir/index"; +import {} from "./dir/index.js"; +import {} from "./dir/index.ts"; + +import { y } from "./redirect"; +>y : Symbol(y, Decl(main.ts, 5, 8)) + +import {} from "./redirect/index"; + +import a from "./types/esm"; +>a : Symbol(a, Decl(main.ts, 8, 6)) + +import * as esm from "./types/esm"; +>esm : Symbol(esm, Decl(main.ts, 9, 6)) + +import b from "./types/cjs"; +>b : Symbol(b, Decl(main.ts, 10, 6)) + +import * as cjs from "./types/cjs"; +>cjs : Symbol(cjs, Decl(main.ts, 11, 6)) + diff --git a/tests/baselines/reference/bundlerRelative1.trace.json b/tests/baselines/reference/bundlerRelative1.trace.json new file mode 100644 index 0000000000000..19e7e28acd7ea --- /dev/null +++ b/tests/baselines/reference/bundlerRelative1.trace.json @@ -0,0 +1,76 @@ +[ + "======== Resolving module './dir' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/dir', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/dir.ts' does not exist.", + "File '/dir.tsx' does not exist.", + "File '/dir.d.ts' does not exist.", + "File '/dir.js' does not exist.", + "File '/dir.jsx' does not exist.", + "File '/dir/package.json' does not exist.", + "File '/dir/index.ts' exist - use it as a name resolution result.", + "======== Module name './dir' was successfully resolved to '/dir/index.ts'. ========", + "======== Resolving module './dir/index' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/dir/index', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/dir/index.ts' exist - use it as a name resolution result.", + "======== Module name './dir/index' was successfully resolved to '/dir/index.ts'. ========", + "======== Resolving module './dir/index.js' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/dir/index.js', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/dir/index.js' has a '.js' extension - stripping it.", + "File '/dir/index.ts' exist - use it as a name resolution result.", + "======== Module name './dir/index.js' was successfully resolved to '/dir/index.ts'. ========", + "======== Resolving module './dir/index.ts' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/dir/index.ts', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File name '/dir/index.ts' has a '.ts' extension - stripping it.", + "File '/dir/index.ts' exist - use it as a name resolution result.", + "======== Module name './dir/index.ts' was successfully resolved to '/dir/index.ts'. ========", + "======== Resolving module './redirect' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/redirect', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/redirect.ts' does not exist.", + "File '/redirect.tsx' does not exist.", + "File '/redirect.d.ts' does not exist.", + "File '/redirect.js' does not exist.", + "File '/redirect.jsx' does not exist.", + "Found 'package.json' at '/redirect/package.json'.", + "'package.json' does not have a 'typesVersions' field.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field '../foo' that references '/foo'.", + "File '/foo' does not exist.", + "Loading module as file / folder, candidate module location '/foo', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/foo.ts' does not exist.", + "File '/foo.tsx' does not exist.", + "File '/foo.d.ts' does not exist.", + "File '/foo.js' does not exist.", + "File '/foo.jsx' does not exist.", + "File '/foo/index.ts' exist - use it as a name resolution result.", + "======== Module name './redirect' was successfully resolved to '/foo/index.ts'. ========", + "======== Resolving module './redirect/index' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/redirect/index', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/redirect/index.ts' does not exist.", + "File '/redirect/index.tsx' does not exist.", + "File '/redirect/index.d.ts' does not exist.", + "File '/redirect/index.js' does not exist.", + "File '/redirect/index.jsx' does not exist.", + "Directory '/redirect/index' does not exist, skipping all lookups in it.", + "======== Module name './redirect/index' was not resolved. ========", + "======== Resolving module './types/esm' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/types/esm', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/types/esm.ts' does not exist.", + "File '/types/esm.tsx' does not exist.", + "File '/types/esm.d.ts' exist - use it as a name resolution result.", + "======== Module name './types/esm' was successfully resolved to '/types/esm.d.ts'. ========", + "======== Resolving module './types/cjs' from '/main.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Loading module as file / folder, candidate module location '/types/cjs', target file types: TypeScript, JavaScript, Declaration, JSON.", + "File '/types/cjs.ts' does not exist.", + "File '/types/cjs.tsx' does not exist.", + "File '/types/cjs.d.ts' exist - use it as a name resolution result.", + "======== Module name './types/cjs' was successfully resolved to '/types/cjs.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/bundlerRelative1.types b/tests/baselines/reference/bundlerRelative1.types new file mode 100644 index 0000000000000..7e1e3e5e865c7 --- /dev/null +++ b/tests/baselines/reference/bundlerRelative1.types @@ -0,0 +1,49 @@ +=== /dir/index.ts === +export const x = 0; +>x : 0 +>0 : 0 + +=== /foo/index.ts === +export const y = 0; +>y : 0 +>0 : 0 + +=== /types/esm.d.ts === +declare const _: string; +>_ : string + +export default _; +>_ : string + +=== /types/cjs.d.ts === +declare const _: string; +>_ : string + +export = _; +>_ : string + +=== /main.ts === +import { x } from "./dir"; +>x : 0 + +import {} from "./dir/index"; +import {} from "./dir/index.js"; +import {} from "./dir/index.ts"; + +import { y } from "./redirect"; +>y : 0 + +import {} from "./redirect/index"; + +import a from "./types/esm"; +>a : string + +import * as esm from "./types/esm"; +>esm : typeof esm + +import b from "./types/cjs"; +>b : string + +import * as cjs from "./types/cjs"; +>cjs : string + diff --git a/tests/baselines/reference/bundlerSyntaxRestrictions.errors.txt b/tests/baselines/reference/bundlerSyntaxRestrictions.errors.txt new file mode 100644 index 0000000000000..bae60c5cc726a --- /dev/null +++ b/tests/baselines/reference/bundlerSyntaxRestrictions.errors.txt @@ -0,0 +1,31 @@ +error TS2468: Cannot find global value 'Promise'. +/main.ts(2,1): error TS5099: Import assignment is not allowed when 'moduleResolution' is set to 'bundler'. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead. +/main.ts(3,1): error TS5100: Export assignment cannot be used when 'moduleResolution' is set to 'bundler'. Consider using 'export default' or another module format instead. +/mainJs.js(2,1): error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option. + + +!!! error TS2468: Cannot find global value 'Promise'. +==== /node_modules/@types/node/index.d.ts (0 errors) ==== + declare var require: (...args: any[]) => any; + +==== /mainJs.js (1 errors) ==== + import {} from "./a"; + import("./a"); + ~~~~~~~~~~~~~ +!!! error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option. + const _ = require("./a"); // No resolution + _.a; // any + +==== /main.ts (2 errors) ==== + import {} from "./a"; + import _ = require("./a"); // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS5099: Import assignment is not allowed when 'moduleResolution' is set to 'bundler'. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead. + export = {}; // Error + ~~~~~~~~~~~~ +!!! error TS5100: Export assignment cannot be used when 'moduleResolution' is set to 'bundler'. Consider using 'export default' or another module format instead. + export {}; + +==== /a.ts (0 errors) ==== + export const a = "a"; + \ No newline at end of file diff --git a/tests/baselines/reference/bundlerSyntaxRestrictions.js b/tests/baselines/reference/bundlerSyntaxRestrictions.js new file mode 100644 index 0000000000000..cd49b3c2efd7d --- /dev/null +++ b/tests/baselines/reference/bundlerSyntaxRestrictions.js @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/moduleResolution/bundler/bundlerSyntaxRestrictions.ts] //// + +//// [index.d.ts] +declare var require: (...args: any[]) => any; + +//// [mainJs.js] +import {} from "./a"; +import("./a"); +const _ = require("./a"); // No resolution +_.a; // any + +//// [main.ts] +import {} from "./a"; +import _ = require("./a"); // Error +export = {}; // Error +export {}; + +//// [a.ts] +export const a = "a"; + + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.a = void 0; +exports.a = "a"; +//// [mainJs.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +Promise.resolve().then(function () { return require("./a"); }); +var _ = require("./a"); // No resolution +_.a; // any +//// [main.js] +"use strict"; +module.exports = {}; diff --git a/tests/baselines/reference/bundlerSyntaxRestrictions.symbols b/tests/baselines/reference/bundlerSyntaxRestrictions.symbols new file mode 100644 index 0000000000000..e48386d570bec --- /dev/null +++ b/tests/baselines/reference/bundlerSyntaxRestrictions.symbols @@ -0,0 +1,29 @@ +=== /node_modules/@types/node/index.d.ts === +declare var require: (...args: any[]) => any; +>require : Symbol(require, Decl(index.d.ts, 0, 11)) +>args : Symbol(args, Decl(index.d.ts, 0, 22)) + +=== /mainJs.js === +import {} from "./a"; +import("./a"); +>"./a" : Symbol("/a", Decl(a.ts, 0, 0)) + +const _ = require("./a"); // No resolution +>_ : Symbol(_, Decl(mainJs.js, 2, 5)) +>require : Symbol(require, Decl(index.d.ts, 0, 11)) + +_.a; // any +>_ : Symbol(_, Decl(mainJs.js, 2, 5)) + +=== /main.ts === +import {} from "./a"; +import _ = require("./a"); // Error +>_ : Symbol(_, Decl(main.ts, 0, 21)) + +export = {}; // Error +export {}; + +=== /a.ts === +export const a = "a"; +>a : Symbol(a, Decl(a.ts, 0, 12)) + diff --git a/tests/baselines/reference/bundlerSyntaxRestrictions.types b/tests/baselines/reference/bundlerSyntaxRestrictions.types new file mode 100644 index 0000000000000..ce832fdb57aa5 --- /dev/null +++ b/tests/baselines/reference/bundlerSyntaxRestrictions.types @@ -0,0 +1,37 @@ +=== /node_modules/@types/node/index.d.ts === +declare var require: (...args: any[]) => any; +>require : (...args: any[]) => any +>args : any[] + +=== /mainJs.js === +import {} from "./a"; +import("./a"); +>import("./a") : Promise +>"./a" : "./a" + +const _ = require("./a"); // No resolution +>_ : any +>require("./a") : any +>require : (...args: any[]) => any +>"./a" : "./a" + +_.a; // any +>_.a : any +>_ : any +>a : any + +=== /main.ts === +import {} from "./a"; +import _ = require("./a"); // Error +>_ : typeof _ + +export = {}; // Error +>{} : {} + +export {}; + +=== /a.ts === +export const a = "a"; +>a : "a" +>"a" : "a" + diff --git a/tests/baselines/reference/config/commandLineParsing/parseCommandLine/Parse empty options of --moduleResolution.js b/tests/baselines/reference/config/commandLineParsing/parseCommandLine/Parse empty options of --moduleResolution.js index fb361238364f5..562f23f1a7748 100644 --- a/tests/baselines/reference/config/commandLineParsing/parseCommandLine/Parse empty options of --moduleResolution.js +++ b/tests/baselines/reference/config/commandLineParsing/parseCommandLine/Parse empty options of --moduleResolution.js @@ -7,4 +7,4 @@ FileNames:: 0.ts Errors:: error TS6044: Compiler option 'moduleResolution' expects an argument. -error TS6046: Argument for '--moduleResolution' option must be: 'node', 'classic', 'node16', 'nodenext'. +error TS6046: Argument for '--moduleResolution' option must be: 'node', 'classic', 'node16', 'nodenext', 'bundler'. 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 19844ec8065fc..5eaa44daaec1e 100644 --- a/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 19844ec8065fc..5eaa44daaec1e 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 19844ec8065fc..5eaa44daaec1e 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 6e28e016bd11d..00903ad0c38a1 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 d73dbd191a220..07e8da2a6e437 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 c4c554e65dffb..ff2c5a0a7e672 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 2368ed9c35291..3955bbd422ede 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 195f29bcb8708..f635f645ea08b 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 19844ec8065fc..5eaa44daaec1e 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 fe6fd06aa610a..ed7f34f5e6557 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 @@ -35,6 +35,10 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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 12daecbe8ed51..cc9d87c258ddb 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 @@ -35,6 +35,10 @@ "types": ["jquery","mocha"], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "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. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "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/allowImportingTsExtensions/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/allowImportingTsExtensions/tsconfig.json new file mode 100644 index 0000000000000..88c95f9eb8307 --- /dev/null +++ b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/allowImportingTsExtensions/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "allowImportingTsExtensions": true + } +} diff --git a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/customConditions/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/customConditions/tsconfig.json new file mode 100644 index 0000000000000..e121ee76bc105 --- /dev/null +++ b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/customConditions/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "customConditions": [] + } +} diff --git a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/resolvePackageJsonExports/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/resolvePackageJsonExports/tsconfig.json new file mode 100644 index 0000000000000..4dc0efaa783ba --- /dev/null +++ b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/resolvePackageJsonExports/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "resolvePackageJsonExports": true + } +} diff --git a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/resolvePackageJsonImports/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/resolvePackageJsonImports/tsconfig.json new file mode 100644 index 0000000000000..a9e8a0f9e1faa --- /dev/null +++ b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/resolvePackageJsonImports/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "resolvePackageJsonImports": true + } +} diff --git a/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).js b/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).js new file mode 100644 index 0000000000000..1ac29a4a032d3 --- /dev/null +++ b/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).js @@ -0,0 +1,33 @@ +//// [tests/cases/conformance/moduleResolution/customConditions.ts] //// + +//// [package.json] +{ + "name": "lodash", + "version": "1.0.0", + "main": "index.js", + "exports": { + "browser": "./browser.js", + "webpack": "./webpack.js", + "default": "./index.js" + } +} + +//// [index.d.ts] +declare const _: "index"; +export = _; + +//// [browser.d.ts] +declare const _: "browser"; +export default _; + +//// [webpack.d.ts] +declare const _: "webpack"; +export = _; + +//// [index.ts] +import _ from "lodash"; + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).symbols b/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).symbols new file mode 100644 index 0000000000000..2b8cae85a8c11 --- /dev/null +++ b/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).symbols @@ -0,0 +1,25 @@ +=== /node_modules/lodash/index.d.ts === +declare const _: "index"; +>_ : Symbol(_, Decl(index.d.ts, 0, 13)) + +export = _; +>_ : Symbol(_, Decl(index.d.ts, 0, 13)) + +=== /node_modules/lodash/browser.d.ts === +declare const _: "browser"; +>_ : Symbol(_, Decl(browser.d.ts, 0, 13)) + +export default _; +>_ : Symbol(_, Decl(browser.d.ts, 0, 13)) + +=== /node_modules/lodash/webpack.d.ts === +declare const _: "webpack"; +>_ : Symbol(_, Decl(webpack.d.ts, 0, 13)) + +export = _; +>_ : Symbol(_, Decl(webpack.d.ts, 0, 13)) + +=== /index.ts === +import _ from "lodash"; +>_ : Symbol(_, Decl(index.ts, 0, 6)) + diff --git a/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).trace.json b/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).trace.json new file mode 100644 index 0000000000000..1b85a4d6fcaf1 --- /dev/null +++ b/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).trace.json @@ -0,0 +1,22 @@ +[ + "======== Resolving module 'lodash' from '/index.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "File '/package.json' does not exist.", + "Loading module 'lodash' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.", + "Found 'package.json' at '/node_modules/lodash/package.json'.", + "File '/node_modules/lodash.ts' does not exist.", + "File '/node_modules/lodash.tsx' does not exist.", + "File '/node_modules/lodash.d.ts' does not exist.", + "'package.json' does not have a 'typesVersions' field.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "'package.json' has 'main' field 'index.js' that references '/node_modules/lodash/index.js'.", + "File '/node_modules/lodash/index.js' does not exist.", + "Loading module as file / folder, candidate module location '/node_modules/lodash/index.js', target file types: TypeScript, Declaration.", + "File name '/node_modules/lodash/index.js' has a '.js' extension - stripping it.", + "File '/node_modules/lodash/index.ts' does not exist.", + "File '/node_modules/lodash/index.tsx' does not exist.", + "File '/node_modules/lodash/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/lodash/index.d.ts', result '/node_modules/lodash/index.d.ts'.", + "======== Module name 'lodash' was successfully resolved to '/node_modules/lodash/index.d.ts' with Package ID 'lodash/index.d.ts@1.0.0'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).types b/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).types new file mode 100644 index 0000000000000..fd913f77aaf75 --- /dev/null +++ b/tests/baselines/reference/customConditions(resolvepackagejsonexports=false).types @@ -0,0 +1,25 @@ +=== /node_modules/lodash/index.d.ts === +declare const _: "index"; +>_ : "index" + +export = _; +>_ : "index" + +=== /node_modules/lodash/browser.d.ts === +declare const _: "browser"; +>_ : "browser" + +export default _; +>_ : "browser" + +=== /node_modules/lodash/webpack.d.ts === +declare const _: "webpack"; +>_ : "webpack" + +export = _; +>_ : "webpack" + +=== /index.ts === +import _ from "lodash"; +>_ : "index" + diff --git a/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).js b/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).js new file mode 100644 index 0000000000000..1ac29a4a032d3 --- /dev/null +++ b/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).js @@ -0,0 +1,33 @@ +//// [tests/cases/conformance/moduleResolution/customConditions.ts] //// + +//// [package.json] +{ + "name": "lodash", + "version": "1.0.0", + "main": "index.js", + "exports": { + "browser": "./browser.js", + "webpack": "./webpack.js", + "default": "./index.js" + } +} + +//// [index.d.ts] +declare const _: "index"; +export = _; + +//// [browser.d.ts] +declare const _: "browser"; +export default _; + +//// [webpack.d.ts] +declare const _: "webpack"; +export = _; + +//// [index.ts] +import _ from "lodash"; + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).symbols b/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).symbols new file mode 100644 index 0000000000000..2b8cae85a8c11 --- /dev/null +++ b/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).symbols @@ -0,0 +1,25 @@ +=== /node_modules/lodash/index.d.ts === +declare const _: "index"; +>_ : Symbol(_, Decl(index.d.ts, 0, 13)) + +export = _; +>_ : Symbol(_, Decl(index.d.ts, 0, 13)) + +=== /node_modules/lodash/browser.d.ts === +declare const _: "browser"; +>_ : Symbol(_, Decl(browser.d.ts, 0, 13)) + +export default _; +>_ : Symbol(_, Decl(browser.d.ts, 0, 13)) + +=== /node_modules/lodash/webpack.d.ts === +declare const _: "webpack"; +>_ : Symbol(_, Decl(webpack.d.ts, 0, 13)) + +export = _; +>_ : Symbol(_, Decl(webpack.d.ts, 0, 13)) + +=== /index.ts === +import _ from "lodash"; +>_ : Symbol(_, Decl(index.ts, 0, 6)) + diff --git a/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).trace.json b/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).trace.json new file mode 100644 index 0000000000000..2019c28fc9f0d --- /dev/null +++ b/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).trace.json @@ -0,0 +1,16 @@ +[ + "======== Resolving module 'lodash' from '/index.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "File '/package.json' does not exist.", + "Loading module 'lodash' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.", + "Found 'package.json' at '/node_modules/lodash/package.json'.", + "Saw non-matching condition 'browser'.", + "Matched 'exports' condition 'webpack'.", + "Using 'exports' subpath '.' with target './webpack.js'.", + "File name '/node_modules/lodash/webpack.js' has a '.js' extension - stripping it.", + "File '/node_modules/lodash/webpack.ts' does not exist.", + "File '/node_modules/lodash/webpack.tsx' does not exist.", + "File '/node_modules/lodash/webpack.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/lodash/webpack.d.ts', result '/node_modules/lodash/webpack.d.ts'.", + "======== Module name 'lodash' was successfully resolved to '/node_modules/lodash/webpack.d.ts' with Package ID 'lodash/webpack.d.ts@1.0.0'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).types b/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).types new file mode 100644 index 0000000000000..4ab420533b366 --- /dev/null +++ b/tests/baselines/reference/customConditions(resolvepackagejsonexports=true).types @@ -0,0 +1,25 @@ +=== /node_modules/lodash/index.d.ts === +declare const _: "index"; +>_ : "index" + +export = _; +>_ : "index" + +=== /node_modules/lodash/browser.d.ts === +declare const _: "browser"; +>_ : "browser" + +export default _; +>_ : "browser" + +=== /node_modules/lodash/webpack.d.ts === +declare const _: "webpack"; +>_ : "webpack" + +export = _; +>_ : "webpack" + +=== /index.ts === +import _ from "lodash"; +>_ : "webpack" + diff --git a/tests/baselines/reference/extensionLoadingPriority(moduleresolution=bundler).symbols b/tests/baselines/reference/extensionLoadingPriority(moduleresolution=bundler).symbols new file mode 100644 index 0000000000000..19522bf41394c --- /dev/null +++ b/tests/baselines/reference/extensionLoadingPriority(moduleresolution=bundler).symbols @@ -0,0 +1,23 @@ +=== /project/a.js === + +export default "a.js"; + +=== /project/a.js.js === + +export default "a.js.js"; + +=== /project/dir/index.ts === + +export default "dir/index.ts"; + +=== /project/dir.js === + +export default "dir.js"; + +=== /project/b.ts === +import a from "./a.js"; +>a : Symbol(a, Decl(b.ts, 0, 6)) + +import dir from "./dir"; +>dir : Symbol(dir, Decl(b.ts, 1, 6)) + diff --git a/tests/baselines/reference/extensionLoadingPriority(moduleresolution=bundler).types b/tests/baselines/reference/extensionLoadingPriority(moduleresolution=bundler).types new file mode 100644 index 0000000000000..b398b344d7017 --- /dev/null +++ b/tests/baselines/reference/extensionLoadingPriority(moduleresolution=bundler).types @@ -0,0 +1,23 @@ +=== /project/a.js === + +export default "a.js"; + +=== /project/a.js.js === + +export default "a.js.js"; + +=== /project/dir/index.ts === + +export default "dir/index.ts"; + +=== /project/dir.js === + +export default "dir.js"; + +=== /project/b.ts === +import a from "./a.js"; +>a : "a.js" + +import dir from "./dir"; +>dir : "dir.js" + diff --git a/tests/baselines/reference/moduleResolution/baseUrl-without-path-mappings-or-rootDirs.js b/tests/baselines/reference/moduleResolution/baseUrl-without-path-mappings-or-rootDirs.js index 7fc2f4fe6403b..3b79ca68b2515 100644 --- a/tests/baselines/reference/moduleResolution/baseUrl-without-path-mappings-or-rootDirs.js +++ b/tests/baselines/reference/moduleResolution/baseUrl-without-path-mappings-or-rootDirs.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder2/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -21,7 +22,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder2/file3.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -30,7 +32,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -39,7 +42,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder2/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -48,7 +52,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder2/file3.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -57,7 +62,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -75,7 +81,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder2/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -84,7 +91,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder2/file3.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -93,7 +101,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -102,7 +111,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder2/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -111,7 +121,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder2/file3.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -120,6 +131,7 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } diff --git a/tests/baselines/reference/moduleResolution/classic-baseUrl-path-mappings.js b/tests/baselines/reference/moduleResolution/classic-baseUrl-path-mappings.js index 48a7deab2e2d5..70def6c942347 100644 --- a/tests/baselines/reference/moduleResolution/classic-baseUrl-path-mappings.js +++ b/tests/baselines/reference/moduleResolution/classic-baseUrl-path-mappings.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -21,7 +22,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder1/file2.ts", @@ -35,7 +37,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -44,7 +47,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/folder1/file3.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder1/file3.ts", diff --git a/tests/baselines/reference/moduleResolution/classic-baseUrl.js b/tests/baselines/reference/moduleResolution/classic-baseUrl.js index 9d1587a3c7bf2..0a9d2f72813fb 100644 --- a/tests/baselines/reference/moduleResolution/classic-baseUrl.js +++ b/tests/baselines/reference/moduleResolution/classic-baseUrl.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/x/m1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -21,7 +22,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/m2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/x/m2.ts", @@ -53,7 +55,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/x/m1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -62,7 +65,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/m2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/x/m2.ts", diff --git a/tests/baselines/reference/moduleResolution/classic-rootDirs.js b/tests/baselines/reference/moduleResolution/classic-rootDirs.js index 7e7d2178995a6..62595ab05cf51 100644 --- a/tests/baselines/reference/moduleResolution/classic-rootDirs.js +++ b/tests/baselines/reference/moduleResolution/classic-rootDirs.js @@ -15,7 +15,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder1/file2.ts", @@ -29,7 +30,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/generated/folder1/file1.ts", @@ -43,7 +45,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/folder1/file1_1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/generated/folder2/folder1/file1_1.ts", diff --git a/tests/baselines/reference/moduleResolution/nested-node-module.js b/tests/baselines/reference/moduleResolution/nested-node-module.js index 3edb344426c60..c1ba22b9f8397 100644 --- a/tests/baselines/reference/moduleResolution/nested-node-module.js +++ b/tests/baselines/reference/moduleResolution/nested-node-module.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/src/libs/guid/dist/guid.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/src/libs/guid.ts", @@ -38,7 +39,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/src/libs/guid/dist/guid.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/src/libs/guid.ts", diff --git a/tests/baselines/reference/moduleResolution/node-baseUrl-path-mappings.js b/tests/baselines/reference/moduleResolution/node-baseUrl-path-mappings.js index a117b795cc23c..30e9c41445cc7 100644 --- a/tests/baselines/reference/moduleResolution/node-baseUrl-path-mappings.js +++ b/tests/baselines/reference/moduleResolution/node-baseUrl-path-mappings.js @@ -24,7 +24,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -33,7 +34,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder1/file2.ts", @@ -51,7 +53,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -60,7 +63,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder2/file3/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder2/file3.ts", @@ -84,7 +88,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder2/file4/dist/types.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder2/file4.ts", @@ -108,7 +113,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/someanotherfolder/file5/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/someanotherfolder/file5.ts", @@ -125,7 +131,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/node_modules/file6.ts", "extension": ".ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/file6.ts", @@ -182,7 +189,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -191,7 +199,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder1/file2.ts", @@ -209,7 +218,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -218,7 +228,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder2/file3/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder2/file3.ts", @@ -242,7 +253,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder2/file4/dist/types.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder2/file4.ts", @@ -266,7 +278,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/someanotherfolder/file5/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/someanotherfolder/file5.ts", @@ -283,7 +296,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/node_modules/file6.ts", "extension": ".ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/file6.ts", diff --git a/tests/baselines/reference/moduleResolution/node-baseUrl.js b/tests/baselines/reference/moduleResolution/node-baseUrl.js index 230672d2b95cb..ecb69b2076974 100644 --- a/tests/baselines/reference/moduleResolution/node-baseUrl.js +++ b/tests/baselines/reference/moduleResolution/node-baseUrl.js @@ -21,7 +21,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/m1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -30,7 +31,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/m2/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/m2.ts", @@ -47,7 +49,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/m3/dist/typings.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/m3.ts", @@ -64,7 +67,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/node_modules/m4.ts", "extension": ".ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/m4.ts", @@ -121,7 +125,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/m1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -130,7 +135,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/m2/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/m2.ts", @@ -147,7 +153,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/m3/dist/typings.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/m3.ts", @@ -164,7 +171,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/node_modules/m4.ts", "extension": ".ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/m4.ts", diff --git a/tests/baselines/reference/moduleResolution/node-rootDirs.js b/tests/baselines/reference/moduleResolution/node-rootDirs.js index dc033c530c744..c3d8dca2b63f3 100644 --- a/tests/baselines/reference/moduleResolution/node-rootDirs.js +++ b/tests/baselines/reference/moduleResolution/node-rootDirs.js @@ -15,7 +15,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder1/file2.ts", @@ -33,7 +34,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/generated/folder1/file1.ts", @@ -51,7 +53,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1_1/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/generated/folder1/file1_1.ts", @@ -87,7 +90,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/generated/folder1/file2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/folder1/file2.ts", @@ -105,7 +109,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/generated/folder1/file1.ts", @@ -123,7 +128,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/root/folder1/file1_1/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/root/generated/folder1/file1_1.ts", diff --git a/tests/baselines/reference/moduleResolution/non-relative-module-name-as-directory.js b/tests/baselines/reference/moduleResolution/non-relative-module-name-as-directory.js index 14229a28387a9..f631d3c016e7b 100644 --- a/tests/baselines/reference/moduleResolution/non-relative-module-name-as-directory.js +++ b/tests/baselines/reference/moduleResolution/non-relative-module-name-as-directory.js @@ -9,7 +9,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/node_modules/foo/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json", @@ -62,7 +63,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/node_modules/foo/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json", diff --git a/tests/baselines/reference/moduleResolution/non-relative-module-name-as-file-ts-files-not-loaded.js b/tests/baselines/reference/moduleResolution/non-relative-module-name-as-file-ts-files-not-loaded.js index 9fc065864bbdd..b30a6b150a505 100644 --- a/tests/baselines/reference/moduleResolution/non-relative-module-name-as-file-ts-files-not-loaded.js +++ b/tests/baselines/reference/moduleResolution/non-relative-module-name-as-file-ts-files-not-loaded.js @@ -9,7 +9,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/b/node_modules/foo.ts", "extension": ".ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/b/c/d/node_modules/foo/package.json", @@ -47,7 +48,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/b/node_modules/foo.ts", "extension": ".ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/b/c/d/node_modules/foo/package.json", diff --git a/tests/baselines/reference/moduleResolution/non-relative-module-name-as-file.js b/tests/baselines/reference/moduleResolution/non-relative-module-name-as-file.js index 48bf3770870e9..4ba986ae2ecf4 100644 --- a/tests/baselines/reference/moduleResolution/non-relative-module-name-as-file.js +++ b/tests/baselines/reference/moduleResolution/non-relative-module-name-as-file.js @@ -9,7 +9,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/b/node_modules/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/b/c/d/node_modules/foo/package.json", @@ -49,7 +50,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/b/node_modules/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/b/c/d/node_modules/foo/package.json", diff --git a/tests/baselines/reference/moduleResolution/non-relative-preserveSymlinks.js b/tests/baselines/reference/moduleResolution/non-relative-preserveSymlinks.js index 5668982afcc90..b5f9ceb12e06c 100644 --- a/tests/baselines/reference/moduleResolution/non-relative-preserveSymlinks.js +++ b/tests/baselines/reference/moduleResolution/non-relative-preserveSymlinks.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedFileName": "/linked/index.d.ts", "originalPath": "/app/node_modules/linked/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/app/node_modules/linked.ts", @@ -40,7 +41,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/app/node_modules/linked/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/app/node_modules/linked.ts", diff --git a/tests/baselines/reference/moduleResolution/non-relative-preserves-originalPath-on-cache-hit.js b/tests/baselines/reference/moduleResolution/non-relative-preserves-originalPath-on-cache-hit.js index 5ed2351fe0247..50b20f9a56ff5 100644 --- a/tests/baselines/reference/moduleResolution/non-relative-preserves-originalPath-on-cache-hit.js +++ b/tests/baselines/reference/moduleResolution/non-relative-preserves-originalPath-on-cache-hit.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedFileName": "/linked/index.d.ts", "originalPath": "/app/node_modules/linked/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/app/src/node_modules/linked/package.json", @@ -43,7 +44,8 @@ Resolution:: { "resolvedFileName": "/linked/index.d.ts", "originalPath": "/app/node_modules/linked/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/app/src/node_modules/linked/package.json", diff --git a/tests/baselines/reference/moduleResolution/non-relative-uses-originalPath-for-caching.js b/tests/baselines/reference/moduleResolution/non-relative-uses-originalPath-for-caching.js index dcc6faae386ea..5508c607f5330 100644 --- a/tests/baselines/reference/moduleResolution/non-relative-uses-originalPath-for-caching.js +++ b/tests/baselines/reference/moduleResolution/non-relative-uses-originalPath-for-caching.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedFileName": "/modules/a.ts", "originalPath": "/sub/node_modules/a/index.ts", "extension": ".ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/sub/dir/node_modules/a/package.json", @@ -41,7 +42,8 @@ Resolution:: { "resolvedFileName": "/modules/a.ts", "originalPath": "/sub/node_modules/a/index.ts", "extension": ".ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/sub/dir/node_modules/a/package.json", diff --git a/tests/baselines/reference/moduleResolution/relative-module-name-as-directory-load-index.js b/tests/baselines/reference/moduleResolution/relative-module-name-as-directory-load-index.js index d13fa757ba9d3..94c2f091ad177 100644 --- a/tests/baselines/reference/moduleResolution/relative-module-name-as-directory-load-index.js +++ b/tests/baselines/reference/moduleResolution/relative-module-name-as-directory-load-index.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/b/foo/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/b/foo.ts", @@ -47,7 +48,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/b/foo/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/b/foo.ts", diff --git a/tests/baselines/reference/moduleResolution/relative-module-name-as-directory-with-invalid-typings.js b/tests/baselines/reference/moduleResolution/relative-module-name-as-directory-with-invalid-typings.js index f23570eb03585..9e5149dce238b 100644 --- a/tests/baselines/reference/moduleResolution/relative-module-name-as-directory-with-invalid-typings.js +++ b/tests/baselines/reference/moduleResolution/relative-module-name-as-directory-with-invalid-typings.js @@ -15,7 +15,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -56,7 +57,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -97,7 +99,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -138,7 +141,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -179,7 +183,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -220,7 +225,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -261,7 +267,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -302,7 +309,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -343,7 +351,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", @@ -384,7 +393,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/node_modules/b/package.json", diff --git a/tests/baselines/reference/moduleResolution/relative-module-name-as-directory.js b/tests/baselines/reference/moduleResolution/relative-module-name-as-directory.js index 05cffbff74acc..33180674c0dd2 100644 --- a/tests/baselines/reference/moduleResolution/relative-module-name-as-directory.js +++ b/tests/baselines/reference/moduleResolution/relative-module-name-as-directory.js @@ -12,7 +12,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/b/c/bar/c/d/e.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/b/c/bar.ts", @@ -38,7 +39,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/b/c/bar/c/d/e.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/b/c/bar.ts", @@ -64,7 +66,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/bar/e.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/bar.ts", @@ -90,7 +93,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/a/bar/e.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/a/bar.ts", @@ -116,7 +120,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/bar/e.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/bar.ts", @@ -142,7 +147,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/bar/e.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/bar.ts", @@ -168,7 +174,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "c:/bar/e.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "c:/bar.ts", @@ -194,7 +201,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "c:/bar/e.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "c:/bar.ts", diff --git a/tests/baselines/reference/moduleResolution/relative-module-name-as-file.js b/tests/baselines/reference/moduleResolution/relative-module-name-as-file.js index a64b27f5761df..79b37762a7635 100644 --- a/tests/baselines/reference/moduleResolution/relative-module-name-as-file.js +++ b/tests/baselines/reference/moduleResolution/relative-module-name-as-file.js @@ -10,7 +10,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/bar/foo.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -25,7 +26,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/bar/foo.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -40,7 +42,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/bar/foo.tsx", "extension": ".tsx", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo/bar/foo.ts" @@ -58,7 +61,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/bar/foo.tsx", "extension": ".tsx", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo/bar/foo.ts" @@ -76,7 +80,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/bar/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo/bar/foo.ts", @@ -95,7 +100,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/bar/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo/bar/foo.ts", @@ -116,7 +122,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/foo.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -131,7 +138,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/foo.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -146,7 +154,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/foo.tsx", "extension": ".tsx", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo/foo.ts" @@ -164,7 +173,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/foo.tsx", "extension": ".tsx", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo/foo.ts" @@ -182,7 +192,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo/foo.ts", @@ -201,7 +212,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo/foo.ts", @@ -222,7 +234,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -237,7 +250,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -252,7 +266,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo.tsx", "extension": ".tsx", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo.ts" @@ -270,7 +285,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo.tsx", "extension": ".tsx", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo.ts" @@ -288,7 +304,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo.ts", @@ -307,7 +324,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/foo.ts", @@ -328,7 +346,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "c:/foo.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -343,7 +362,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "c:/foo.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } @@ -358,7 +378,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "c:/foo.tsx", "extension": ".tsx", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "c:/foo.ts" @@ -376,7 +397,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "c:/foo.tsx", "extension": ".tsx", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "c:/foo.ts" @@ -394,7 +416,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "c:/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "c:/foo.ts", @@ -413,7 +436,8 @@ Resolution:: { "resolvedModule": { "resolvedFileName": "c:/foo.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "c:/foo.ts", diff --git a/tests/baselines/reference/packageJsonImportsExportsOptionCompat(moduleresolution=classic).errors.txt b/tests/baselines/reference/packageJsonImportsExportsOptionCompat(moduleresolution=classic).errors.txt new file mode 100644 index 0000000000000..93ffdb73d1766 --- /dev/null +++ b/tests/baselines/reference/packageJsonImportsExportsOptionCompat(moduleresolution=classic).errors.txt @@ -0,0 +1,8 @@ +error TS5098: Option 'resolvePackageJsonExports' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'. +error TS5098: Option 'resolvePackageJsonImports' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'. + + +!!! error TS5098: Option 'resolvePackageJsonExports' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'. +!!! error TS5098: Option 'resolvePackageJsonImports' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'. +==== tests/cases/conformance/moduleResolution/index.ts (0 errors) ==== + \ No newline at end of file diff --git a/tests/baselines/reference/packageJsonImportsExportsOptionCompat(moduleresolution=node).errors.txt b/tests/baselines/reference/packageJsonImportsExportsOptionCompat(moduleresolution=node).errors.txt new file mode 100644 index 0000000000000..93ffdb73d1766 --- /dev/null +++ b/tests/baselines/reference/packageJsonImportsExportsOptionCompat(moduleresolution=node).errors.txt @@ -0,0 +1,8 @@ +error TS5098: Option 'resolvePackageJsonExports' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'. +error TS5098: Option 'resolvePackageJsonImports' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'. + + +!!! error TS5098: Option 'resolvePackageJsonExports' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'. +!!! error TS5098: Option 'resolvePackageJsonImports' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'. +==== tests/cases/conformance/moduleResolution/index.ts (0 errors) ==== + \ No newline at end of file diff --git a/tests/baselines/reference/reuseProgramStructure/can-reuse-module-resolutions-from-non-modified-files.js b/tests/baselines/reference/reuseProgramStructure/can-reuse-module-resolutions-from-non-modified-files.js index 83f3d24b636ae..0bbadac80d050 100644 --- a/tests/baselines/reference/reuseProgramStructure/can-reuse-module-resolutions-from-non-modified-files.js +++ b/tests/baselines/reference/reuseProgramStructure/can-reuse-module-resolutions-from-non-modified-files.js @@ -53,7 +53,8 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: @@ -79,14 +80,16 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } ./f1: { "resolvedModule": { "resolvedFileName": "f1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: @@ -187,7 +190,8 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: @@ -213,14 +217,16 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } ./f1: { "resolvedModule": { "resolvedFileName": "f1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: @@ -310,7 +316,8 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined @@ -326,14 +333,16 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } ./f1: { "resolvedModule": { "resolvedFileName": "f1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: @@ -418,7 +427,8 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined @@ -434,14 +444,16 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } ./f1: { "resolvedModule": { "resolvedFileName": "f1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: @@ -525,7 +537,8 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined @@ -541,14 +554,16 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } ./f1: { "resolvedModule": { "resolvedFileName": "f1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: @@ -630,7 +645,8 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined @@ -646,14 +662,16 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } ./f1: { "resolvedModule": { "resolvedFileName": "f1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: @@ -747,14 +765,16 @@ resolvedModules: "resolvedModule": { "resolvedFileName": "b2.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } ./f1: { "resolvedModule": { "resolvedFileName": "f1.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: diff --git a/tests/baselines/reference/reuseProgramStructure/change-affects-a-single-module-of-a-package.js b/tests/baselines/reference/reuseProgramStructure/change-affects-a-single-module-of-a-package.js index 1ab1a4b919ced..a6ec1e0691cbd 100644 --- a/tests/baselines/reference/reuseProgramStructure/change-affects-a-single-module-of-a-package.js +++ b/tests/baselines/reference/reuseProgramStructure/change-affects-a-single-module-of-a-package.js @@ -20,7 +20,8 @@ resolvedModules: "name": "b", "subModuleName": "internal.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/internal.ts", @@ -46,7 +47,8 @@ b: { "name": "b", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b.ts", @@ -89,7 +91,8 @@ resolvedModules: "name": "b", "subModuleName": "internal.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/internal.ts", @@ -115,7 +118,8 @@ b: { "name": "b", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b.ts", diff --git a/tests/baselines/reference/reuseProgramStructure/change-affects-imports.js b/tests/baselines/reference/reuseProgramStructure/change-affects-imports.js index edc9d673707b4..b1af4711871a3 100644 --- a/tests/baselines/reference/reuseProgramStructure/change-affects-imports.js +++ b/tests/baselines/reference/reuseProgramStructure/change-affects-imports.js @@ -54,7 +54,8 @@ b: { "resolvedModule": { "resolvedFileName": "b.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined diff --git a/tests/baselines/reference/reuseProgramStructure/fetches-imports-after-npm-install.js b/tests/baselines/reference/reuseProgramStructure/fetches-imports-after-npm-install.js index 271483c51fddc..1c4e39c7c86ba 100644 --- a/tests/baselines/reference/reuseProgramStructure/fetches-imports-after-npm-install.js +++ b/tests/baselines/reference/reuseProgramStructure/fetches-imports-after-npm-install.js @@ -76,7 +76,8 @@ a: { "resolvedModule": { "resolvedFileName": "node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "node_modules/a/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/redirect-no-change.js b/tests/baselines/reference/reuseProgramStructure/redirect-no-change.js index edd5b77800c85..d6851e614b653 100644 --- a/tests/baselines/reference/reuseProgramStructure/redirect-no-change.js +++ b/tests/baselines/reference/reuseProgramStructure/redirect-no-change.js @@ -20,7 +20,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -56,7 +57,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -80,7 +82,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -95,7 +98,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", @@ -136,7 +140,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -172,7 +177,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -196,7 +202,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -211,7 +218,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/redirect-previous-duplicate-packages.js b/tests/baselines/reference/reuseProgramStructure/redirect-previous-duplicate-packages.js index 6af47acec2e56..f7a11625082e9 100644 --- a/tests/baselines/reference/reuseProgramStructure/redirect-previous-duplicate-packages.js +++ b/tests/baselines/reference/reuseProgramStructure/redirect-previous-duplicate-packages.js @@ -20,7 +20,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -56,7 +57,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.4" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -80,7 +82,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -95,7 +98,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", @@ -138,7 +142,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -174,7 +179,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -198,7 +204,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -213,7 +220,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/redirect-target-changes.js b/tests/baselines/reference/reuseProgramStructure/redirect-target-changes.js index 4afced0c95b7c..83f61703a58aa 100644 --- a/tests/baselines/reference/reuseProgramStructure/redirect-target-changes.js +++ b/tests/baselines/reference/reuseProgramStructure/redirect-target-changes.js @@ -20,7 +20,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -56,7 +57,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -80,7 +82,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -95,7 +98,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", @@ -131,7 +135,8 @@ x: { "resolvedModule": { "resolvedFileName": "/node_modules/a/node_modules/x/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -167,7 +172,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -191,7 +197,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -206,7 +213,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/redirect-underlying-changes.js b/tests/baselines/reference/reuseProgramStructure/redirect-underlying-changes.js index f8d4c09bc12a7..b22376b0f96a6 100644 --- a/tests/baselines/reference/reuseProgramStructure/redirect-underlying-changes.js +++ b/tests/baselines/reference/reuseProgramStructure/redirect-underlying-changes.js @@ -20,7 +20,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -56,7 +57,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -80,7 +82,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -95,7 +98,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", @@ -136,7 +140,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -172,7 +177,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.4" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -196,7 +202,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -211,7 +218,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-no-change.js b/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-no-change.js index edd5b77800c85..d6851e614b653 100644 --- a/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-no-change.js +++ b/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-no-change.js @@ -20,7 +20,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -56,7 +57,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -80,7 +82,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -95,7 +98,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", @@ -136,7 +140,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -172,7 +177,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -196,7 +202,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -211,7 +218,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-previous-duplicate-packages.js b/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-previous-duplicate-packages.js index 6af47acec2e56..f7a11625082e9 100644 --- a/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-previous-duplicate-packages.js +++ b/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-previous-duplicate-packages.js @@ -20,7 +20,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -56,7 +57,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.4" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -80,7 +82,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -95,7 +98,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", @@ -138,7 +142,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -174,7 +179,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -198,7 +204,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -213,7 +220,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-target-changes.js b/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-target-changes.js index 4afced0c95b7c..83f61703a58aa 100644 --- a/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-target-changes.js +++ b/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-target-changes.js @@ -20,7 +20,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -56,7 +57,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -80,7 +82,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -95,7 +98,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", @@ -131,7 +135,8 @@ x: { "resolvedModule": { "resolvedFileName": "/node_modules/a/node_modules/x/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -167,7 +172,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -191,7 +197,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -206,7 +213,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-underlying-changes.js b/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-underlying-changes.js index f8d4c09bc12a7..b22376b0f96a6 100644 --- a/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-underlying-changes.js +++ b/tests/baselines/reference/reuseProgramStructure/redirect-with-getSourceFileByPath-underlying-changes.js @@ -20,7 +20,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -56,7 +57,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -80,7 +82,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -95,7 +98,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", @@ -136,7 +140,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.3" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/node_modules/x.ts", @@ -172,7 +177,8 @@ x: { "name": "x", "subModuleName": "index.d.ts", "version": "1.2.4" - } + }, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/node_modules/x.ts", @@ -196,7 +202,8 @@ a: { "resolvedModule": { "resolvedFileName": "/node_modules/a/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/a/package.json", @@ -211,7 +218,8 @@ b: { "resolvedModule": { "resolvedFileName": "/node_modules/b/index.d.ts", "extension": ".d.ts", - "isExternalLibraryImport": true + "isExternalLibraryImport": true, + "resolvedUsingTsExtension": false }, "failedLookupLocations": [ "/node_modules/b/package.json", diff --git a/tests/baselines/reference/reuseProgramStructure/resolution-cache-follows-imports.js b/tests/baselines/reference/reuseProgramStructure/resolution-cache-follows-imports.js index 4cb70b6e9ac1b..5ccc36f9fb50f 100644 --- a/tests/baselines/reference/reuseProgramStructure/resolution-cache-follows-imports.js +++ b/tests/baselines/reference/reuseProgramStructure/resolution-cache-follows-imports.js @@ -15,7 +15,8 @@ b: { "resolvedModule": { "resolvedFileName": "b.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined @@ -44,7 +45,8 @@ b: { "resolvedModule": { "resolvedFileName": "b.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined @@ -89,7 +91,8 @@ b: { "resolvedModule": { "resolvedFileName": "b.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } c: { diff --git a/tests/baselines/reference/reuseProgramStructure/resolvedImports-after-re-using-an-ambient-external-module-declaration.js b/tests/baselines/reference/reuseProgramStructure/resolvedImports-after-re-using-an-ambient-external-module-declaration.js index 362434f1dafdd..3de657beb7949 100644 --- a/tests/baselines/reference/reuseProgramStructure/resolvedImports-after-re-using-an-ambient-external-module-declaration.js +++ b/tests/baselines/reference/reuseProgramStructure/resolvedImports-after-re-using-an-ambient-external-module-declaration.js @@ -8,7 +8,8 @@ a: { "resolvedModule": { "resolvedFileName": "/a.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined @@ -29,7 +30,8 @@ a: { "resolvedModule": { "resolvedFileName": "/a.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined diff --git a/tests/baselines/reference/reuseProgramStructure/works-with-updated-SourceFiles.js b/tests/baselines/reference/reuseProgramStructure/works-with-updated-SourceFiles.js index 90c3cb70935f7..269048aa8cfd2 100644 --- a/tests/baselines/reference/reuseProgramStructure/works-with-updated-SourceFiles.js +++ b/tests/baselines/reference/reuseProgramStructure/works-with-updated-SourceFiles.js @@ -8,7 +8,8 @@ a: { "resolvedModule": { "resolvedFileName": "/a.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined @@ -30,7 +31,8 @@ a: { "resolvedModule": { "resolvedFileName": "/a.ts", "extension": ".ts", - "isExternalLibraryImport": false + "isExternalLibraryImport": false, + "resolvedUsingTsExtension": false } } resolvedTypeReferenceDirectiveNames: undefined diff --git a/tests/baselines/reference/showConfig/Shows tsconfig for single option/allowImportingTsExtensions/tsconfig.json b/tests/baselines/reference/showConfig/Shows tsconfig for single option/allowImportingTsExtensions/tsconfig.json new file mode 100644 index 0000000000000..88c95f9eb8307 --- /dev/null +++ b/tests/baselines/reference/showConfig/Shows tsconfig for single option/allowImportingTsExtensions/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "allowImportingTsExtensions": true + } +} diff --git a/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js b/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js index 12b3d134c26e8..cb8ce333a59cd 100644 --- a/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js +++ b/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js @@ -1143,6 +1143,7 @@ Info 32 [00:01:13.000] response: "2842", "2843", "2844", + "2846", "4000", "4002", "4004", @@ -1293,6 +1294,11 @@ Info 32 [00:01:13.000] response: "5093", "5094", "5095", + "5096", + "5097", + "5098", + "5099", + "5100", "6044", "6045", "6046", @@ -2463,6 +2469,7 @@ Info 38 [00:01:19.000] response: "2842", "2843", "2844", + "2846", "4000", "4002", "4004", @@ -2613,6 +2620,11 @@ Info 38 [00:01:19.000] response: "5093", "5094", "5095", + "5096", + "5097", + "5098", + "5099", + "5100", "6044", "6045", "6046", @@ -3695,6 +3707,7 @@ Info 40 [00:01:21.000] response: "2842", "2843", "2844", + "2846", "4000", "4002", "4004", @@ -3845,6 +3858,11 @@ Info 40 [00:01:21.000] response: "5093", "5094", "5095", + "5096", + "5097", + "5098", + "5099", + "5100", "6044", "6045", "6046", diff --git a/tests/cases/conformance/moduleResolution/bundler/bundlerImportESM.ts b/tests/cases/conformance/moduleResolution/bundler/bundlerImportESM.ts new file mode 100644 index 0000000000000..86107d98fbcab --- /dev/null +++ b/tests/cases/conformance/moduleResolution/bundler/bundlerImportESM.ts @@ -0,0 +1,13 @@ +// @moduleResolution: bundler + +// @Filename: /esm.mts +export const esm = 0; + +// @Filename: /not-actually-cjs.cts +import { esm } from "./esm.mjs"; + +// @Filename: /package.json +{ "type": "commonjs" } + +// @Filename: /still-not-cjs.ts +import { esm } from "./esm.mjs"; diff --git a/tests/cases/conformance/moduleResolution/bundler/bundlerImportTsExtensions.ts b/tests/cases/conformance/moduleResolution/bundler/bundlerImportTsExtensions.ts new file mode 100644 index 0000000000000..8ba4b62b7116b --- /dev/null +++ b/tests/cases/conformance/moduleResolution/bundler/bundlerImportTsExtensions.ts @@ -0,0 +1,73 @@ +// @moduleResolution: bundler +// @outDir: dist +// @allowJs: true +// @checkJs: true +// @outDir: out +// @noEmit: true,false +// @allowImportingTsExtensions: true,false +// @traceResolution: true + +// @Filename: /project/a.ts +export {}; + +// @Filename: /project/b.ts +export {}; + +// @Filename: /project/b.js +export {}; + +// @Filename: /project/b.d.ts +export {}; + +// @Filename: /project/c.ts +export {}; + +// @Filename: /project/c.tsx +export {}; + +// @Filename: /project/d/index.ts +export {}; + +// @Filename: /project/e +WOMP WOMP BINARY DATA + +// @Filename: /project/e.ts +export {}; + +// @Filename: /project/e.txt +The letter e is for elephant +This poem is not about elephants +It is about the letter e +- Authored by GitHub Copilot, Nov 2022 + +// @Filename: /project/e.txt.ts +export {}; + +// @Filename: /project/main.ts +import {} from "./a"; +import {} from "./a.js"; +import {} from "./a.ts"; + +import {} from "./b"; +import {} from "./b.js"; +import {} from "./b.ts"; +import {} from "./b.d.ts"; +import type {} from "./b.d.ts"; + +import {} from "./c.ts"; +import {} from "./c.tsx"; + +import {} from "./d"; +import {} from "./d/index"; +import {} from "./d/index.ts"; + +// These should not resolve, but preventing them has +// relatively little utility compared to the cost of +// the filesystem hits. +import {} from "./e"; +import {} from "./e.txt"; + +// @Filename: /project/types.d.ts +import {} from "./a.ts"; +import {} from "./a.d.ts"; +import type {} from "./a.d.ts"; \ No newline at end of file diff --git a/tests/cases/conformance/moduleResolution/bundler/bundlerNodeModules1.ts b/tests/cases/conformance/moduleResolution/bundler/bundlerNodeModules1.ts new file mode 100644 index 0000000000000..ffa7242ff3c09 --- /dev/null +++ b/tests/cases/conformance/moduleResolution/bundler/bundlerNodeModules1.ts @@ -0,0 +1,38 @@ +// @moduleResolution: bundler +// @traceResolution: true + +// @Filename: /node_modules/dual/package.json +{ + "name": "dual", + "version": "1.0.0", + "type": "module", + "main": "index.cjs", + "types": "index.d.cts", + "exports": { + ".": { + "import": "./index.js", + "require": "./index.cjs" + } + } +} + +// @Filename: /node_modules/dual/index.js +export const esm = 0; + +// @Filename: /node_modules/dual/index.d.ts +export const esm: number; + +// @Filename: /node_modules/dual/index.cjs +exports.cjs = 0; + +// @Filename: /node_modules/dual/index.d.cts +export const cjs: number; + +// @Filename: /main.ts +import { esm, cjs } from "dual"; + +// @Filename: /main.mts +import { esm, cjs } from "dual"; + +// @Filename: /main.cts +import { esm, cjs } from "dual"; diff --git a/tests/cases/conformance/moduleResolution/bundler/bundlerRelative1.ts b/tests/cases/conformance/moduleResolution/bundler/bundlerRelative1.ts new file mode 100644 index 0000000000000..d23292176f8d4 --- /dev/null +++ b/tests/cases/conformance/moduleResolution/bundler/bundlerRelative1.ts @@ -0,0 +1,33 @@ +// @moduleResolution: bundler +// @traceResolution: true + +// @Filename: /dir/index.ts +export const x = 0; + +// @Filename: /redirect/package.json +{ "main": "../foo" } + +// @Filename: /foo/index.ts +export const y = 0; + +// @Filename: /types/esm.d.ts +declare const _: string; +export default _; + +// @Filename: /types/cjs.d.ts +declare const _: string; +export = _; + +// @Filename: /main.ts +import { x } from "./dir"; +import {} from "./dir/index"; +import {} from "./dir/index.js"; +import {} from "./dir/index.ts"; + +import { y } from "./redirect"; +import {} from "./redirect/index"; + +import a from "./types/esm"; +import * as esm from "./types/esm"; +import b from "./types/cjs"; +import * as cjs from "./types/cjs"; diff --git a/tests/cases/conformance/moduleResolution/bundler/bundlerSyntaxRestrictions.ts b/tests/cases/conformance/moduleResolution/bundler/bundlerSyntaxRestrictions.ts new file mode 100644 index 0000000000000..fdc7f7c77819d --- /dev/null +++ b/tests/cases/conformance/moduleResolution/bundler/bundlerSyntaxRestrictions.ts @@ -0,0 +1,22 @@ +// @moduleResolution: bundler +// @checkJs: true +// @allowJs: true +// @outDir: out + +// @Filename: /node_modules/@types/node/index.d.ts +declare var require: (...args: any[]) => any; + +// @Filename: /mainJs.js +import {} from "./a"; +import("./a"); +const _ = require("./a"); // No resolution +_.a; // any + +// @Filename: /main.ts +import {} from "./a"; +import _ = require("./a"); // Error +export = {}; // Error +export {}; + +// @Filename: /a.ts +export const a = "a"; diff --git a/tests/cases/conformance/moduleResolution/customConditions.ts b/tests/cases/conformance/moduleResolution/customConditions.ts new file mode 100644 index 0000000000000..47fb048ac28bf --- /dev/null +++ b/tests/cases/conformance/moduleResolution/customConditions.ts @@ -0,0 +1,31 @@ +// @moduleResolution: bundler +// @customConditions: webpack, browser +// @resolvePackageJsonExports: true, false +// @traceResolution: true + +// @Filename: /node_modules/lodash/package.json +{ + "name": "lodash", + "version": "1.0.0", + "main": "index.js", + "exports": { + "browser": "./browser.js", + "webpack": "./webpack.js", + "default": "./index.js" + } +} + +// @Filename: /node_modules/lodash/index.d.ts +declare const _: "index"; +export = _; + +// @Filename: /node_modules/lodash/browser.d.ts +declare const _: "browser"; +export default _; + +// @Filename: /node_modules/lodash/webpack.d.ts +declare const _: "webpack"; +export = _; + +// @Filename: /index.ts +import _ from "lodash"; diff --git a/tests/cases/conformance/moduleResolution/extensionLoadingPriority.ts b/tests/cases/conformance/moduleResolution/extensionLoadingPriority.ts index 7686c3dfedf61..c3a06a36b52aa 100644 --- a/tests/cases/conformance/moduleResolution/extensionLoadingPriority.ts +++ b/tests/cases/conformance/moduleResolution/extensionLoadingPriority.ts @@ -1,4 +1,4 @@ -// @moduleResolution: classic,node,node16,nodenext +// @moduleResolution: classic,node,node16,nodenext,bundler // @allowJs: true // @checkJs: true // @noEmit: true diff --git a/tests/cases/conformance/moduleResolution/packageJsonImportsExportsOptionCompat.ts b/tests/cases/conformance/moduleResolution/packageJsonImportsExportsOptionCompat.ts new file mode 100644 index 0000000000000..b1bf3811d6e64 --- /dev/null +++ b/tests/cases/conformance/moduleResolution/packageJsonImportsExportsOptionCompat.ts @@ -0,0 +1,7 @@ +// @moduleResolution: classic, node, node16, nodenext, bundler +// @resolvePackageJsonImports: true +// @resolvePackageJsonExports: true +// @noTypesAndSymbols: true +// @noEmit: true + +// @Filename: index.ts \ No newline at end of file diff --git a/tests/cases/fourslash/autoImportAllowTsExtensions1.ts b/tests/cases/fourslash/autoImportAllowTsExtensions1.ts new file mode 100644 index 0000000000000..e71867ceb67d8 --- /dev/null +++ b/tests/cases/fourslash/autoImportAllowTsExtensions1.ts @@ -0,0 +1,22 @@ +/// + +// @moduleResolution: bundler +// @allowImportingTsExtensions: true +// @noEmit: true + +// @Filename: /node_modules/@types/foo/index.d.ts +//// export const fromAtTypesFoo: number; + +// @Filename: /node_modules/bar/index.d.ts +//// export const fromBar: number; + +// @Filename: /local.ts +//// export const fromLocal: number; + +// @Filename: /Component.tsx +//// export function Component() { return null; } + +// @Filename: /main.ts +//// /**/ + +verify.baselineAutoImports(""); diff --git a/tests/cases/fourslash/autoImportAllowTsExtensions2.ts b/tests/cases/fourslash/autoImportAllowTsExtensions2.ts new file mode 100644 index 0000000000000..5fd8b0730bbf0 --- /dev/null +++ b/tests/cases/fourslash/autoImportAllowTsExtensions2.ts @@ -0,0 +1,22 @@ +/// + +// @moduleResolution: bundler +// @allowImportingTsExtensions: true +// @noEmit: true + +// @Filename: /node_modules/@types/foo/index.d.ts +//// export const fromAtTypesFoo: number; + +// @Filename: /node_modules/bar/index.d.ts +//// export const fromBar: number; + +// @Filename: /local.ts +//// export const fromLocal: number; + +// @Filename: /Component.tsx +//// export function Component() { return null; } + +// @Filename: /main.ts +//// /**/ + +verify.baselineAutoImports("", { importModuleSpecifierEnding: "js" }); diff --git a/tests/cases/fourslash/autoImportAllowTsExtensions3.ts b/tests/cases/fourslash/autoImportAllowTsExtensions3.ts new file mode 100644 index 0000000000000..d6e38bf236e1d --- /dev/null +++ b/tests/cases/fourslash/autoImportAllowTsExtensions3.ts @@ -0,0 +1,20 @@ +/// + +// @moduleResolution: bundler +// @allowImportingTsExtensions: true +// @noEmit: true + +// @Filename: /local.ts +//// export const fromLocal: number; + +// @Filename: /decl.d.ts +//// export const fromDecl: number; + +// @Filename: /Component.tsx +//// export function Component() { return null; } + +// @Filename: /main.ts +//// import { Component } from "./Component.tsx"; +//// /**/ + +verify.baselineAutoImports(""); diff --git a/tests/cases/fourslash/autoImportAllowTsExtensions4.ts b/tests/cases/fourslash/autoImportAllowTsExtensions4.ts new file mode 100644 index 0000000000000..b4f479fef5bf9 --- /dev/null +++ b/tests/cases/fourslash/autoImportAllowTsExtensions4.ts @@ -0,0 +1,20 @@ +/// + +// @moduleResolution: bundler +// @allowImportingTsExtensions: true +// @noEmit: true + +// @Filename: /local.ts +//// export const fromLocal: number; + +// @Filename: /decl.d.ts +//// export const fromDecl: number; + +// @Filename: /Component.tsx +//// export function Component() { return null; } + +// @Filename: /main.ts +//// import { Component } from "./local.js"; +//// /**/ + +verify.baselineAutoImports(""); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 7d106808e7982..5bbbd00212ccb 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -375,6 +375,7 @@ declare namespace FourSlashInterface { getAndApplyCodeFix(errorCode?: number, index?: number): void; importFixAtPosition(expectedTextArray: string[], errorCode?: number, options?: UserPreferences): void; importFixModuleSpecifiers(marker: string, moduleSpecifiers: string[], options?: UserPreferences): void; + baselineAutoImports(marker: string, options?: UserPreferences): void; navigationBar(json: any, options?: { checkSpans?: boolean }): void; navigationTree(json: any, options?: { checkSpans?: boolean }): void; diff --git a/tests/cases/fourslash/pathCompletionsAllowTsExtensions.ts b/tests/cases/fourslash/pathCompletionsAllowTsExtensions.ts new file mode 100644 index 0000000000000..b871ce1f429e4 --- /dev/null +++ b/tests/cases/fourslash/pathCompletionsAllowTsExtensions.ts @@ -0,0 +1,36 @@ +/// + +// @moduleResolution: bundler +// @allowImportingTsExtensions: true +// @noEmit: true + +// @Filename: /project/foo.ts +//// export const foo = 0; + +// @Filename: /project/main.ts +//// import {} from ".//**/" + +// Extensionless by default +verify.completions({ + marker: "", + isNewIdentifierLocation: true, + exact: ["foo"], +}); + +// .ts extension when allowImportingTsExtensions is true and setting is js... +verify.completions({ + marker: "", + isNewIdentifierLocation: true, + exact: ["foo.ts"], + preferences: { + importModuleSpecifierEnding: "js", + }, +}); + +// ...or when another import uses .ts extension +edit.insert(`foo.ts"\nimport {} from "./`); +verify.completions({ + marker: "", + isNewIdentifierLocation: true, + exact: ["foo.ts"], +});