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"], +}); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy