From dc5cd9676bfe36cf2e68cb7ce63f3662acc5dc06 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 27 Aug 2018 12:06:45 -0700 Subject: [PATCH] Switch to paths-like pattern matching --- src/compiler/diagnosticMessages.json | 6 +- src/compiler/moduleNameResolver.ts | 553 ++++++++++-------- src/compiler/moduleSpecifiers.ts | 40 +- src/compiler/transformers/declarations.ts | 7 + src/services/pathCompletions.ts | 63 +- ...age_relativeImportWithinPackage.trace.json | 2 +- ...ativeImportWithinPackage_scoped.trace.json | 2 +- .../reference/library-reference-10.trace.json | 6 +- .../reference/library-reference-11.trace.json | 2 +- .../reference/library-reference-12.trace.json | 2 +- .../reference/library-reference-2.trace.json | 6 +- ...lutionWithExtensions_unexpected.trace.json | 4 +- ...utionWithExtensions_unexpected2.trace.json | 4 +- ...on_packageJson_notAtPackageRoot.trace.json | 2 +- ...AtPackageRoot_fakeScopedPackage.trace.json | 2 +- ...ution_packageJson_scopedPackage.trace.json | 2 +- ...ageRoot_mainFieldInSubDirectory.trace.json | 2 +- .../reference/packageJsonMain.trace.json | 12 +- .../packageJsonMain_isNonRecursive.trace.json | 4 +- ...eactTransitiveImportHasValidDeclaration.js | 1 - .../reference/typesVersions.ambientModules.js | 2 +- .../typesVersions.ambientModules.trace.json | 31 +- .../reference/typesVersions.multiFile.js | 2 +- .../typesVersions.multiFile.trace.json | 24 +- .../typesVersionsDeclarationEmit.ambient.js | 51 ++ ...pesVersionsDeclarationEmit.ambient.symbols | 37 ++ ...VersionsDeclarationEmit.ambient.trace.json | 55 ++ ...typesVersionsDeclarationEmit.ambient.types | 33 ++ .../typesVersionsDeclarationEmit.multiFile.js | 48 ++ ...sVersionsDeclarationEmit.multiFile.symbols | 47 ++ ...rsionsDeclarationEmit.multiFile.trace.json | 37 ++ ...pesVersionsDeclarationEmit.multiFile.types | 37 ++ .../reference/typingsLookup4.trace.json | 20 +- .../typesVersionsDeclarationEmit.ambient.ts | 43 ++ .../typesVersionsDeclarationEmit.multiFile.ts | 39 ++ .../typesVersions.ambientModules.ts | 2 +- .../typesVersions.multiFile.ts | 2 +- ...tionForStringLiteralNonrelativeImport13.ts | 4 +- 38 files changed, 877 insertions(+), 359 deletions(-) create mode 100644 tests/baselines/reference/typesVersionsDeclarationEmit.ambient.js create mode 100644 tests/baselines/reference/typesVersionsDeclarationEmit.ambient.symbols create mode 100644 tests/baselines/reference/typesVersionsDeclarationEmit.ambient.trace.json create mode 100644 tests/baselines/reference/typesVersionsDeclarationEmit.ambient.types create mode 100644 tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.js create mode 100644 tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.symbols create mode 100644 tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.trace.json create mode 100644 tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.types create mode 100644 tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.ambient.ts create mode 100644 tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.multiFile.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ebe5c3efbcd..69cc7c018f4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3671,7 +3671,7 @@ "category": "Error", "code": 6205 }, - "'package.json' has invalid version '{0}' in 'typesVersions' field.": { + "'package.json' has a 'typesVersions' field with version-specific path mappings.": { "category": "Message", "code": 6206 }, @@ -3679,6 +3679,10 @@ "category": "Message", "code": 6207 }, + "'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'.": { + "category": "Message", + "code": 6208 + }, "Projects to reference": { "category": "Message", diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 3b61c2cd83b..6545ce353e6 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -24,6 +24,13 @@ namespace ts { return withPackageId(/*packageId*/ undefined, r); } + function removeIgnoredPackageId(r: Resolved | undefined): PathAndExtension | undefined { + if (r) { + Debug.assert(r.packageId === undefined); + return { path: r.path, ext: r.extension }; + } + } + /** Result of trying to resolve a module. */ interface Resolved { path: string; @@ -82,13 +89,14 @@ namespace ts { host: ModuleResolutionHost; compilerOptions: CompilerOptions; traceEnabled: boolean; + failedLookupLocations: Push; } /** Just the fields that we use for module resolution. */ interface PackageJsonPathFields { typings?: string; types?: string; - typesVersions?: MapLike; + typesVersions?: MapLike>; main?: string; } @@ -97,42 +105,89 @@ namespace ts { version?: string; } - /** Reads from "main" or "types"/"typings" depending on `extensions`. */ - function tryReadPackageJsonFields(readTypes: boolean, jsonContent: PackageJsonPathFields, baseDirectory: string, state: ModuleResolutionState): string | undefined { - return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); + type MatchingKeys = K extends (TRecord[K] extends TMatch ? K : never) ? K : never; - function tryReadFromField(fieldName: "typings" | "types" | "main"): string | undefined { - if (!hasProperty(jsonContent, fieldName)) { - if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, fieldName); - } - return; - } - - const fileName = jsonContent[fieldName]; - if (!isString(fileName)) { - if (state.traceEnabled) { - trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, "string", typeof fileName); - } - return; - } - - const path = normalizePath(combinePaths(baseDirectory, fileName)); + function readPackageJsonField>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined; + function readPackageJsonField>(jsonContent: PackageJson, fieldName: K, typeOfTag: "object", state: ModuleResolutionState): PackageJson[K] | undefined; + function readPackageJsonField(jsonContent: PackageJson, fieldName: K, typeOfTag: "string" | "object", state: ModuleResolutionState): PackageJson[K] | undefined { + if (!hasProperty(jsonContent, fieldName)) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path); + trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, fieldName); } - return path; + return; } + const value = jsonContent[fieldName]; + if (typeof value !== typeOfTag || value === null) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value); + } + return; + } + return value; } - /* @internal */ - export function getPackageJsonTypesVersionsOverride(typesVersions: MapLike) { - return getPackageJsonTypesVersionsOverrideWithTrace(typesVersions, /*state*/ undefined); + function readPackageJsonPathField(jsonContent: PackageJson, fieldName: K, baseDirectory: string, state: ModuleResolutionState): PackageJson[K] | undefined { + const fileName = readPackageJsonField(jsonContent, fieldName, "string", state); + if (fileName === undefined) return; + const path = normalizePath(combinePaths(baseDirectory, fileName)); + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path); + } + return path; + } + + function readPackageJsonTypesFields(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState) { + return readPackageJsonPathField(jsonContent, "typings", baseDirectory, state) + || readPackageJsonPathField(jsonContent, "types", baseDirectory, state); + } + + function readPackageJsonMainField(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState) { + return readPackageJsonPathField(jsonContent, "main", baseDirectory, state); + } + + function readPackageJsonTypesVersionsField(jsonContent: PackageJson, state: ModuleResolutionState) { + const typesVersions = readPackageJsonField(jsonContent, "typesVersions", "object", state); + if (typesVersions === undefined) return; + + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_has_a_typesVersions_field_with_version_specific_path_mappings); + } + + return typesVersions; + } + + interface VersionPaths { + version: string; + paths: MapLike; + } + + function readPackageJsonTypesVersionPaths(jsonContent: PackageJson, state: ModuleResolutionState): VersionPaths | undefined { + const typesVersions = readPackageJsonTypesVersionsField(jsonContent, state); + if (typesVersions === undefined) return; + + const result = getPackageJsonTypesVersionsPaths(typesVersions); + if (!result) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, versionMajorMinor); + } + return; + } + + const { version: bestVersionKey, paths: bestVersionPaths } = result; + if (typeof bestVersionPaths !== "object") { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersions['${bestVersionKey}']`, "object", typeof bestVersionPaths); + } + return; + } + + return result; } let typeScriptVersion: Version | undefined; - function getPackageJsonTypesVersionsOverrideWithTrace(typesVersions: MapLike, state: ModuleResolutionState | undefined) { + /* @internal */ + export function getPackageJsonTypesVersionsPaths(typesVersions: MapLike>) { if (!typeScriptVersion) typeScriptVersion = new Version(versionMajorMinor); let bestVersion: Version | undefined; @@ -142,9 +197,6 @@ namespace ts { const keyVersion = Version.tryParse(key); if (keyVersion === undefined) { - if (state && state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_invalid_version_0_in_typesVersions_field, key); - } continue; } @@ -160,47 +212,7 @@ namespace ts { return; } - return { version: bestVersionKey, directory: typesVersions[bestVersionKey] }; - } - - function tryReadPackageJsonTypesVersion(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState): string | undefined { - if (!hasProperty(jsonContent, "typesVersions")) { - if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, "typesVersions"); - } - return; - } - - const typesVersions = jsonContent.typesVersions; - if (typeof typesVersions !== "object") { - if (state.traceEnabled) { - trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, "typesVersions", "object", typeof typesVersions); - } - return; - } - - const result = getPackageJsonTypesVersionsOverrideWithTrace(typesVersions, state); - if (!result) { - if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, versionMajorMinor); - } - return; - } - - const { version: bestVersionKey, directory: bestVersionPath } = result; - if (!isString(bestVersionPath)) { - if (state.traceEnabled) { - trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersions['${bestVersionKey}']`, "string", typeof bestVersionPath); - } - return; - } - - if (state.traceEnabled) { - const path = normalizePath(combinePaths(baseDirectory, bestVersionPath)); - trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, `typesVersions['${bestVersionKey}']`, bestVersionPath, path); - } - - return bestVersionPath; + return { version: bestVersionKey, paths: typesVersions[bestVersionKey] }; } export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined { @@ -250,7 +262,8 @@ namespace ts { */ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations { const traceEnabled = isTraceEnabled(options, host); - const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled }; + const failedLookupLocations: string[] = []; + const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations }; const typeRoots = getEffectiveTypeRoots(options, host); if (traceEnabled) { @@ -272,8 +285,6 @@ namespace ts { } } - const failedLookupLocations: string[] = []; - let resolved = primaryLookup(); let primary = true; if (!resolved) { @@ -309,7 +320,7 @@ namespace ts { trace(host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory); } return resolvedTypeScriptOnly( - loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, failedLookupLocations, + loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, !directoryExists, moduleResolutionState)); }); } @@ -328,7 +339,7 @@ namespace ts { if (traceEnabled) { trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup); } - const result = loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*cache*/ undefined); + const result = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined); const resolvedFile = resolvedTypeScriptOnly(result && result.value); if (!resolvedFile && traceEnabled) { trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName); @@ -366,7 +377,7 @@ namespace ts { if (host.directoryExists(root)) { for (const typeDirectivePath of host.getDirectories(root)) { const normalized = normalizePath(typeDirectivePath); - const packageJsonPath = pathToPackageJson(combinePaths(root, normalized)); + const packageJsonPath = combinePaths(root, normalized, "package.json"); // `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types. // See `createNotNeededPackageJSON` in the types-publisher` repo. // tslint:disable-next-line:no-null-keyword @@ -589,7 +600,7 @@ namespace ts { * 'typings' entry or file 'index' with some supported extension * - Classic loader will only try to interpret '/a/b/c' as file. */ - type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined; + type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined; /** * Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to @@ -652,18 +663,18 @@ namespace ts { * entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location. */ function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader, - failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { + state: ModuleResolutionState): Resolved | undefined { if (!isExternalModuleNameRelative(moduleName)) { - return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state); + return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state); } else { - return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state); + return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, state); } } function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader, - failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { + state: ModuleResolutionState): Resolved | undefined { if (!state.compilerOptions.rootDirs) { return undefined; @@ -708,7 +719,7 @@ namespace ts { if (state.traceEnabled) { trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate); } - const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state); + const resolvedFileName = loader(extensions, candidate, !directoryProbablyExists(containingDirectory, state.host), state); if (resolvedFileName) { return resolvedFileName; } @@ -727,7 +738,7 @@ namespace ts { trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate); } const baseDirectory = getDirectoryPath(candidate); - const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state); + const resolvedFileName = loader(extensions, candidate, !directoryProbablyExists(baseDirectory, state.host), state); if (resolvedFileName) { return resolvedFileName; } @@ -739,59 +750,28 @@ namespace ts { return undefined; } - function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { - if (!state.compilerOptions.baseUrl) { + function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState): Resolved | undefined { + const { baseUrl, paths } = state.compilerOptions; + if (!baseUrl) { return undefined; } if (state.traceEnabled) { - trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, state.compilerOptions.baseUrl, moduleName); + trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName); } - - // string is for exact match - let matchedPattern: Pattern | string | undefined; - if (state.compilerOptions.paths) { + if (paths) { if (state.traceEnabled) { trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName); } - matchedPattern = matchPatternOrExact(getOwnKeys(state.compilerOptions.paths), moduleName); - } - - if (matchedPattern) { - const matchedStar = isString(matchedPattern) ? undefined : matchedText(matchedPattern, moduleName); - const matchedPatternText = isString(matchedPattern) ? matchedPattern : patternText(matchedPattern); - if (state.traceEnabled) { - trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText); + const resolved = tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state); + if (resolved) { + return resolved.value; } - return forEach(state.compilerOptions.paths![matchedPatternText], subst => { - const path = matchedStar ? subst.replace("*", matchedStar) : subst; - const candidate = normalizePath(combinePaths(state.compilerOptions.baseUrl!, path)); - if (state.traceEnabled) { - trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path); - } - // A path mapping may have an extension, in contrast to an import, which should omit it. - const extension = tryGetExtensionFromPath(candidate); - if (extension !== undefined) { - const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state); - if (path !== undefined) { - return noPackageId({ path, ext: extension }); - } - } - - return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state); - }); } - else { - const candidate = normalizePath(combinePaths(state.compilerOptions.baseUrl, moduleName)); - if (state.traceEnabled) { - trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, state.compilerOptions.baseUrl, candidate); - } - - return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state); + const candidate = normalizePath(combinePaths(baseUrl, moduleName)); + if (state.traceEnabled) { + trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate); } - } - - export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations { - return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false); + return loader(extensions, candidate, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state); } /** @@ -809,11 +789,15 @@ namespace ts { return resolvedModule.resolvedFileName; } + export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations { + return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false); + } + function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); const failedLookupLocations: string[] = []; - const state: ModuleResolutionState = { compilerOptions, host, traceEnabled }; + const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations }; const result = jsOnly ? tryResolve(Extensions.JavaScript) : @@ -827,8 +811,8 @@ namespace ts { return { resolvedModule: undefined, failedLookupLocations }; function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> { - const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true); - const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state); + const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true); + const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state); if (resolved) { return toSearchResult({ resolved, isExternalLibraryImport: stringContains(resolved.path, nodeModulesPathPart) }); } @@ -837,7 +821,7 @@ namespace ts { if (traceEnabled) { trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } - const resolved = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); + const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache); if (!resolved) return undefined; let resolvedValue = resolved.value; @@ -851,7 +835,7 @@ namespace ts { } else { const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName)); - const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true); + const resolved = nodeLoadModuleByRelativeName(extensions, candidate, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true); // Treat explicit "node_modules" import as an external library import. return resolved && toSearchResult({ resolved, isExternalLibraryImport: contains(parts, "node_modules") }); } @@ -871,7 +855,7 @@ namespace ts { return real; } - function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson: boolean): Resolved | undefined { + function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson: boolean): Resolved | undefined { if (state.traceEnabled) { trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]); } @@ -885,10 +869,11 @@ namespace ts { onlyRecordFailures = true; } } - const resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); + const resolvedFromFile = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state); if (resolvedFromFile) { const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined; - const packageId = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, failedLookupLocations, /*onlyRecordFailures*/ false, state).packageId; + const packageInfo = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, /*onlyRecordFailures*/ false, state); + const packageId = packageInfo && packageInfo.packageId; return withPackageId(packageId, resolvedFromFile); } } @@ -901,7 +886,7 @@ namespace ts { onlyRecordFailures = true; } } - return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); + return loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson); } /*@internal*/ @@ -953,22 +938,22 @@ namespace ts { return path + "/index.d.ts"; } - function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined { - return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state)); + function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined { + return noPackageId(loadModuleFromFile(extensions, candidate, onlyRecordFailures, state)); } /** * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations. */ - function loadModuleFromFile(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { + function loadModuleFromFile(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { if (extensions === Extensions.Json) { const extensionLess = tryRemoveExtension(candidate, Extension.Json); - return extensionLess === undefined ? undefined : tryAddingExtensions(extensionLess, extensions, failedLookupLocations, onlyRecordFailures, state); + return extensionLess === undefined ? undefined : tryAddingExtensions(extensionLess, extensions, onlyRecordFailures, state); } // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts" - const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state); + const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, onlyRecordFailures, state); if (resolvedByAddingExtension) { return resolvedByAddingExtension; } @@ -981,12 +966,12 @@ namespace ts { const extension = candidate.substring(extensionless.length); trace(state.host, Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } - return tryAddingExtensions(extensionless, extensions, failedLookupLocations, onlyRecordFailures, state); + return tryAddingExtensions(extensionless, extensions, onlyRecordFailures, state); } } /** Try to return an existing file that adds one of the `extensions` to `candidate`. */ - function tryAddingExtensions(candidate: string, extensions: Extensions, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { + function tryAddingExtensions(candidate: string, extensions: Extensions, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { if (!onlyRecordFailures) { // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing const directory = getDirectoryPath(candidate); @@ -1007,13 +992,13 @@ namespace ts { } function tryExtension(ext: Extension): PathAndExtension | undefined { - const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); + const path = tryFile(candidate + ext, onlyRecordFailures, state); return path === undefined ? undefined : { path, ext }; } } /** Return the file if it exists. */ - function tryFile(fileName: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined { + function tryFile(fileName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined { if (!onlyRecordFailures) { if (state.host.fileExists(fileName)) { if (state.traceEnabled) { @@ -1027,52 +1012,48 @@ namespace ts { } } } - failedLookupLocations.push(fileName); + state.failedLookupLocations.push(fileName); return undefined; } - function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) { - const { packageJsonContent, packageId, versionPath } = considerPackageJson - ? getPackageJsonInfo(candidate, "", failedLookupLocations, onlyRecordFailures, state) - : { packageJsonContent: undefined, packageId: undefined, versionPath: undefined }; - if (versionPath) { - candidate = normalizePath(combinePaths(candidate, versionPath)); - } - return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent)); + function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) { + const packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, "", onlyRecordFailures, state) : undefined; + const packageId = packageInfo && packageInfo.packageId; + const packageJsonContent = packageInfo && packageInfo.packageJsonContent; + const versionPaths = packageJsonContent && readPackageJsonTypesVersionPaths(packageJsonContent, state); + return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths)); } - function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJsonPathFields | undefined): PathAndExtension | undefined { - const fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, extensions, candidate, failedLookupLocations, state); + function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJsonPathFields | undefined, versionPaths: VersionPaths | undefined): PathAndExtension | undefined { + const fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, versionPaths, extensions, candidate, state); if (fromPackageJson) { return fromPackageJson; } const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); - return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); + return loadModuleFromFile(extensions, combinePaths(candidate, "index"), !directoryExists, state); } - function getPackageJsonInfo( - nodeModuleDirectory: string, - subModuleName: string, - failedLookupLocations: Push, - onlyRecordFailures: boolean, - state: ModuleResolutionState, - ): { found: boolean, packageJsonContent: PackageJsonPathFields | undefined, packageId: PackageId | undefined, versionPath: string | undefined } { + interface PackageJsonInfo { + packageJsonContent: PackageJsonPathFields | undefined; + packageId: PackageId | undefined; + versionPaths: VersionPaths | undefined; + } + + function getPackageJsonInfo(packageDirectory: string, subModuleName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined { const { host, traceEnabled } = state; - const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host); - const packageJsonPath = pathToPackageJson(nodeModuleDirectory); + const directoryExists = !onlyRecordFailures && directoryProbablyExists(packageDirectory, host); + const packageJsonPath = combinePaths(packageDirectory, "package.json"); if (directoryExists && host.fileExists(packageJsonPath)) { const packageJsonContent = readJson(packageJsonPath, host) as PackageJson; - const versionPath = tryReadPackageJsonTypesVersion(packageJsonContent, nodeModuleDirectory, state); if (subModuleName === "") { // looking up the root - need to handle types/typings/main redirects for subModuleName - const versionDirectory = versionPath ? normalizePath(combinePaths(nodeModuleDirectory, versionPath)) : nodeModuleDirectory; - const path = tryReadPackageJsonFields(/*readTypes*/ true, packageJsonContent, versionDirectory, state); + const path = readPackageJsonTypesFields(packageJsonContent, packageDirectory, state); if (typeof path === "string") { - subModuleName = addExtensionAndIndex(path.substring(versionDirectory.length + 1)); + subModuleName = addExtensionAndIndex(path.substring(packageDirectory.length + 1)); } else { - const jsPath = tryReadPackageJsonFields(/*readTypes*/ false, packageJsonContent, nodeModuleDirectory, state); - if (typeof jsPath === "string" && jsPath.length > nodeModuleDirectory.length) { - const potentialSubModule = jsPath.substring(nodeModuleDirectory.length + 1); + const jsPath = readPackageJsonMainField(packageJsonContent, packageDirectory, state); + if (typeof jsPath === "string" && jsPath.length > packageDirectory.length) { + const potentialSubModule = jsPath.substring(packageDirectory.length + 1); subModuleName = (forEach(supportedJavascriptExtensions, extension => tryRemoveExtension(potentialSubModule, extension)) || potentialSubModule) + Extension.Dts; } @@ -1082,13 +1063,11 @@ namespace ts { } } - if (versionPath) { - subModuleName = combinePaths(versionPath, subModuleName); - } - if (!endsWith(subModuleName, Extension.Dts)) { subModuleName = addExtensionAndIndex(subModuleName); } + + const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state); const packageId: PackageId | undefined = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string" ? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version } : undefined; @@ -1100,7 +1079,8 @@ namespace ts { trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); } } - return { found: true, packageJsonContent, packageId, versionPath }; + + return { packageJsonContent, packageId, versionPaths }; } else { if (directoryExists && traceEnabled) { @@ -1108,17 +1088,18 @@ namespace ts { } // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results - failedLookupLocations.push(packageJsonPath); - return { found: false, packageJsonContent: undefined, packageId: undefined, versionPath: undefined }; + state.failedLookupLocations.push(packageJsonPath); } } - function loadModuleFromPackageJson(jsonContent: PackageJsonPathFields, extensions: Extensions, candidate: string, failedLookupLocations: Push, state: ModuleResolutionState): PathAndExtension | undefined { - let file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript && extensions !== Extensions.Json, jsonContent, candidate, state); + function loadModuleFromPackageJson(jsonContent: PackageJsonPathFields, versionPaths: VersionPaths | undefined, extensions: Extensions, candidate: string, state: ModuleResolutionState): PathAndExtension | undefined { + let file = extensions !== Extensions.JavaScript && extensions !== Extensions.Json + ? readPackageJsonTypesFields(jsonContent, candidate, state) + : readPackageJsonMainField(jsonContent, candidate, state); if (!file) { if (extensions === Extensions.TypeScript) { // When resolving typescript modules, try resolving using main field as well - file = tryReadPackageJsonFields(/*readTypes*/ false, jsonContent, candidate, state); + file = readPackageJsonMainField(jsonContent, candidate, state); if (!file) { return undefined; } @@ -1128,27 +1109,39 @@ namespace ts { } } - const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(file), state.host); - const fromFile = tryFile(file, failedLookupLocations, onlyRecordFailures, state); - if (fromFile) { - const resolved = resolvedIfExtensionMatches(extensions, fromFile); - if (resolved) { - return resolved; + const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => { + const fromFile = tryFile(candidate, onlyRecordFailures, state); + if (fromFile) { + const resolved = resolvedIfExtensionMatches(extensions, fromFile); + if (resolved) { + return noPackageId(resolved); + } + if (state.traceEnabled) { + trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile); + } } + + // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types" + const nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; + // Don't do package.json lookup recursively, because Node.js' package lookup doesn't. + return nodeLoadModuleByRelativeName(nextExtensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ false); + }; + + const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(file), state.host); + + if (versionPaths && containsPath(candidate, file)) { + const moduleName = getRelativePathFromDirectory(candidate, file, /*ignoreCase*/ false); if (state.traceEnabled) { - trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile); + trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, versionMajorMinor, moduleName); + } + const result = tryLoadModuleUsingPaths(extensions, moduleName, candidate, versionPaths.paths, loader, onlyRecordFailures, state); + if (result) { + return removeIgnoredPackageId(result.value); } } - // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types" - const nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; - // Don't do package.json lookup recursively, because Node.js' package lookup doesn't. - const result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false); - if (result) { - // It won't have a `packageId` set, because we disabled `considerPackageJson`. - Debug.assert(result.packageId === undefined); - return { path: result.path, ext: result.extension }; - } + // It won't have a `packageId` set, because we disabled `considerPackageJson`. + return removeIgnoredPackageId(loader(extensions, file, onlyRecordFailures, state)); } /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ @@ -1171,42 +1164,6 @@ namespace ts { } } - function pathToPackageJson(directory: string): string { - return combinePaths(directory, "package.json"); - } - - function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { - let candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName)); - // First look for a nested package.json, as in `node_modules/foo/bar/package.json`. - let packageJsonContent: PackageJsonPathFields | undefined; - let versionPath: string | undefined; - let packageId: PackageId | undefined; - const packageInfo = getPackageJsonInfo(candidate, "", failedLookupLocations, /*onlyRecordFailures*/ !nodeModulesFolderExists, state); - if (packageInfo.found) { - ({ packageJsonContent, packageId, versionPath } = packageInfo); - - // If package.json supplied a typescript-version prefix path, apply it to the candidate. - if (versionPath) { - candidate = normalizePath(combinePaths(candidate, versionPath)); - } - } - else { - const { packageName, rest } = parsePackageName(moduleName); - if (rest !== "") { // If "rest" is empty, we just did this search above. - const packageRootPath = combinePaths(nodeModulesFolder, packageName); - // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId. - ({ packageId, versionPath } = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state)); - // If package.json supplied a typescript-version prefix path, apply it to the candidate. - if (versionPath) { - candidate = normalizePath(combinePaths(packageRootPath, versionPath, rest)); - } - } - } - const pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || - loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent); - return withPackageId(packageId, pathAndExtension); - } - /* @internal */ export function parsePackageName(moduleName: string): { packageName: string, rest: string } { let idx = moduleName.indexOf(directorySeparator); @@ -1216,35 +1173,36 @@ namespace ts { return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) }; } - function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult { - return loadModuleFromNearestNodeModules(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false, cache); - } - function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState): SearchResult { - // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly. - return loadModuleFromNearestNodeModules(Extensions.DtsOnly, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ true, /*cache*/ undefined); + function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult { + return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache); } - function loadModuleFromNearestNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState, typesOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult { + function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName: string, directory: string, state: ModuleResolutionState): SearchResult { + // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly. + return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined); + } + + function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult { const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName); return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => { if (getBaseFileName(ancestorDirectory) !== "node_modules") { - const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host, failedLookupLocations); + const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state); if (resolutionFromCache) { return resolutionFromCache; } - return toSearchResult(loadModuleFromImmediateNodeModules(extensions, moduleName, ancestorDirectory, failedLookupLocations, state, typesOnly)); + return toSearchResult(loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, ancestorDirectory, state, typesScopeOnly)); } }); } - function loadModuleFromImmediateNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState, typesOnly: boolean): Resolved | undefined { + function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean): Resolved | undefined { const nodeModulesFolder = combinePaths(directory, "node_modules"); const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host); if (!nodeModulesFolderExists && state.traceEnabled) { trace(state.host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder); } - const packageResult = typesOnly ? undefined : loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state); + const packageResult = typesScopeOnly ? undefined : loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, state); if (packageResult) { return packageResult; } @@ -1257,7 +1215,84 @@ namespace ts { } nodeModulesAtTypesExists = false; } - return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, mangleScopedPackageNameWithTrace(moduleName, state), nodeModulesAtTypes, nodeModulesAtTypesExists, failedLookupLocations, state); + return loadModuleFromSpecificNodeModulesDirectory(Extensions.DtsOnly, mangleScopedPackageNameWithTrace(moduleName, state), nodeModulesAtTypes, nodeModulesAtTypesExists, state); + } + } + + function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, moduleName: string, nodeModulesDirectory: string, nodeModulesDirectoryExists: boolean, state: ModuleResolutionState): Resolved | undefined { + const candidate = normalizePath(combinePaths(nodeModulesDirectory, moduleName)); + + // First look for a nested package.json, as in `node_modules/foo/bar/package.json`. + let packageJsonContent: PackageJsonPathFields | undefined; + let packageId: PackageId | undefined; + let versionPaths: VersionPaths | undefined; + + const packageInfo = getPackageJsonInfo(candidate, "", !nodeModulesDirectoryExists, state); + if (packageInfo) { + ({ packageJsonContent, packageId, versionPaths } = packageInfo); + const fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state); + if (fromFile) { + return noPackageId(fromFile); + } + + const fromDirectory = loadNodeModuleFromDirectoryWorker(extensions, candidate, !nodeModulesDirectoryExists, state, packageJsonContent, versionPaths); + return withPackageId(packageId, fromDirectory); + } + + const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => { + const pathAndExtension = + loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) || + loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths); + return withPackageId(packageId, pathAndExtension); + }; + + const { packageName, rest } = parsePackageName(moduleName); + if (rest !== "") { // If "rest" is empty, we just did this search above. + const packageDirectory = combinePaths(nodeModulesDirectory, packageName); + + // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings. + const packageInfo = getPackageJsonInfo(packageDirectory, rest, !nodeModulesDirectoryExists, state); + if (packageInfo) ({ packageId, versionPaths } = packageInfo); + if (versionPaths) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, versionMajorMinor, rest); + } + const packageDirectoryExists = nodeModulesDirectoryExists && directoryProbablyExists(packageDirectory, state.host); + const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, versionPaths.paths, loader, !packageDirectoryExists, state); + if (fromPaths) { + return fromPaths.value; + } + } + } + + return loader(extensions, candidate, !nodeModulesDirectoryExists, state); + } + + function tryLoadModuleUsingPaths(extensions: Extensions, moduleName: string, baseDirectory: string, paths: MapLike, loader: ResolutionKindSpecificLoader, onlyRecordFailures: boolean, state: ModuleResolutionState): SearchResult { + const matchedPattern = matchPatternOrExact(getOwnKeys(paths), moduleName); + if (matchedPattern) { + const matchedStar = isString(matchedPattern) ? undefined : matchedText(matchedPattern, moduleName); + const matchedPatternText = isString(matchedPattern) ? matchedPattern : patternText(matchedPattern); + if (state.traceEnabled) { + trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText); + } + const resolved = forEach(paths[matchedPatternText], subst => { + const path = matchedStar ? subst.replace("*", matchedStar) : subst; + const candidate = normalizePath(combinePaths(baseDirectory, path)); + if (state.traceEnabled) { + trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path); + } + // A path mapping may have an extension, in contrast to an import, which should omit it. + const extension = tryGetExtensionFromPath(candidate); + if (extension !== undefined) { + const path = tryFile(candidate, onlyRecordFailures, state); + if (path !== undefined) { + return noPackageId({ path, ext: extension }); + } + } + return loader(extensions, candidate, onlyRecordFailures || !directoryProbablyExists(getDirectoryPath(candidate), state.host), state); + }); + return { value: resolved }; } } @@ -1305,21 +1340,21 @@ namespace ts { typesPackageName; } - function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost, failedLookupLocations: Push): SearchResult { + function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, state: ModuleResolutionState): SearchResult { const result = cache && cache.get(containingDirectory); if (result) { - if (traceEnabled) { - trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory); + if (state.traceEnabled) { + trace(state.host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory); } - failedLookupLocations.push(...result.failedLookupLocations); + state.failedLookupLocations.push(...result.failedLookupLocations); return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, originalPath: result.resolvedModule.originalPath || true, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); - const state: ModuleResolutionState = { compilerOptions, host, traceEnabled }; const failedLookupLocations: string[] = []; + const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations }; const containingDirectory = getDirectoryPath(containingFile); const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); @@ -1327,7 +1362,7 @@ namespace ts { return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations); function tryResolve(extensions: Extensions): SearchResult { - const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state); + const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, state); if (resolvedUsingSettings) { return { value: resolvedUsingSettings }; } @@ -1336,24 +1371,24 @@ namespace ts { const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName); // Climb up parent directories looking for a module. const resolved = forEachAncestorDirectory(containingDirectory, directory => { - const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host, failedLookupLocations); + const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state); if (resolutionFromCache) { return resolutionFromCache; } const searchName = normalizePath(combinePaths(directory, moduleName)); - return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, /*onlyRecordFailures*/ false, state)); }); if (resolved) { return resolved; } if (extensions === Extensions.TypeScript) { // If we didn't find the file normally, look it up in @types. - return loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state); + return loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, containingDirectory, state); } } else { const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); - return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state)); + return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, /*onlyRecordFailures*/ false, state)); } } } @@ -1368,9 +1403,9 @@ namespace ts { if (traceEnabled) { trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache); } - const state: ModuleResolutionState = { compilerOptions, host, traceEnabled }; const failedLookupLocations: string[] = []; - const resolved = loadModuleFromImmediateNodeModules(Extensions.DtsOnly, moduleName, globalCache, failedLookupLocations, state, /*typesOnly*/ false); + const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations }; + const resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false); return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations); } diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 696736048b1..5035fd52ec9 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -260,7 +260,8 @@ namespace ts.moduleSpecifiers { const suffix = pattern.substr(indexOfStar + 1); if (relativeToBaseUrl.length >= prefix.length + suffix.length && startsWith(relativeToBaseUrl, prefix) && - endsWith(relativeToBaseUrl, suffix)) { + endsWith(relativeToBaseUrl, suffix) || + !suffix && relativeToBaseUrl === removeTrailingDirectorySeparator(prefix)) { const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); return key.replace("*", matchedStar); } @@ -318,6 +319,26 @@ namespace ts.moduleSpecifiers { return undefined; } + const packageRootPath = moduleFileName.substring(0, parts.packageRootIndex); + const packageJsonPath = combinePaths(packageRootPath, "package.json"); + const packageJsonContent = host.fileExists!(packageJsonPath) + ? JSON.parse(host.readFile!(packageJsonPath)!) + : undefined; + const versionPaths = packageJsonContent && packageJsonContent.typesVersions + ? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions) + : undefined; + if (versionPaths) { + const subModuleName = moduleFileName.slice(parts.packageRootIndex + 1); + const fromPaths = tryGetModuleNameFromPaths( + removeFileExtension(subModuleName), + removeExtensionAndIndexPostFix(subModuleName, ModuleResolutionKind.NodeJs, /*addJsExtension*/ false), + versionPaths.paths + ); + if (fromPaths !== undefined) { + moduleFileName = combinePaths(moduleFileName.slice(0, parts.packageRootIndex), fromPaths); + } + } + // Simplify the full file path to something that can be resolved by Node. // If the module could be imported by a directory name, use that directory's name @@ -330,17 +351,12 @@ namespace ts.moduleSpecifiers { function getDirectoryOrExtensionlessFileName(path: string): string { // If the file is the main module, it can be imported by the package name - const packageRootPath = path.substring(0, parts.packageRootIndex); - const packageJsonPath = combinePaths(packageRootPath, "package.json"); - if (host.fileExists!(packageJsonPath)) { // TODO: GH#18217 - const packageJsonContent = JSON.parse(host.readFile!(packageJsonPath)!); - if (packageJsonContent) { - const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; - if (mainFileRelative) { - const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName); - if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(path))) { - return packageRootPath; - } + if (packageJsonContent) { + const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; + if (mainFileRelative) { + const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName); + if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(path))) { + return packageRootPath; } } } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 063b5f1cd1d..e33d9eec292 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -289,6 +289,13 @@ namespace ts { if (startsWith(fileName, "./") && hasExtension(fileName)) { fileName = fileName.substring(2); } + + // omit references to files from node_modules (npm may disambiguate module + // references when installing this package, making the path is unreliable). + if (startsWith(fileName, "node_modules/") || fileName.indexOf("/node_modules/") !== -1) { + return; + } + references.push({ pos: -1, end: -1, fileName }); } }; diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index f958163bb14..22cc56903c0 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -107,24 +107,10 @@ namespace ts.Completions.PathCompletions { // const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); // TODO(rbuckton): should use resolvePaths const absolutePath = resolvePath(scriptPath, fragment); - let baseDirectory = hasTrailingDirectorySeparator(absolutePath) ? absolutePath : getDirectoryPath(absolutePath); + const baseDirectory = hasTrailingDirectorySeparator(absolutePath) ? absolutePath : getDirectoryPath(absolutePath); const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); if (tryDirectoryExists(host, baseDirectory)) { - // 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 result = getPackageJsonTypesVersionsOverride(typesVersions); - const versionPath = result && result.directory; - if (versionPath) { - baseDirectory = resolvePath(baseDirectory, versionPath); - } - } - } - // Enumerate the available files if possible const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]); @@ -165,11 +151,41 @@ namespace ts.Completions.PathCompletions { } } } + + // 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 versionResult = getPackageJsonTypesVersionsPaths(typesVersions); + const versionPaths = versionResult && versionResult.paths; + const rest = absolutePath.slice(ensureTrailingDirectorySeparator(baseDirectory).length); + if (versionPaths) { + addCompletionEntriesFromPaths(result, rest, baseDirectory, extensions, versionPaths, host); + } + } + } } return result; } + function addCompletionEntriesFromPaths(result: NameAndKind[], fragment: string, baseDirectory: string, fileExtensions: ReadonlyArray, paths: MapLike, host: LanguageServiceHost) { + for (const path in paths) { + if (!hasProperty(paths, path)) continue; + const patterns = paths[path]; + if (patterns) { + for (const { name, kind } of getCompletionsForPathMapping(path, patterns, fragment, baseDirectory, fileExtensions, host)) { + // Path mappings may provide a duplicate way to get to something we've already added, so don't add again. + if (!result.some(entry => entry.name === name)) { + result.push(nameAndKind(name, kind)); + } + } + } + } + } + /** * Check all of the declared modules and those in node modules. Possible sources of modules: * Modules that are found by the type checker @@ -185,19 +201,10 @@ namespace ts.Completions.PathCompletions { const fileExtensions = getSupportedExtensionsForModuleResolution(compilerOptions); if (baseUrl) { const projectDir = compilerOptions.project || host.getCurrentDirectory(); - const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl); - getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, host, /*exclude*/ undefined, result); - - for (const path in paths!) { - const patterns = paths![path]; - if (paths!.hasOwnProperty(path) && patterns) { - for (const { name, kind } of getCompletionsForPathMapping(path, patterns, fragment, baseUrl, fileExtensions, host)) { - // Path mappings may provide a duplicate way to get to something we've already added, so don't add again. - if (!result.some(entry => entry.name === name)) { - result.push(nameAndKind(name, kind)); - } - } - } + const absolute = normalizePath(combinePaths(projectDir, baseUrl)); + getCompletionEntriesForDirectoryFragment(fragment, absolute, fileExtensions, /*includeExtensions*/ false, host, /*exclude*/ undefined, result); + if (paths) { + addCompletionEntriesFromPaths(result, fragment, absolute, fileExtensions, paths, host); } } diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json index dbf67e3802c..c4421e45579 100644 --- a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json @@ -33,10 +33,10 @@ "======== Resolving module 'foo' from '/node_modules/a/index.d.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", - "'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' does not have a 'main' field.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'. Package ID is 'foo/index.d.ts@1.2.3'.", "File '/node_modules/a/node_modules/foo.ts' does not exist.", "File '/node_modules/a/node_modules/foo.tsx' does not exist.", diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json index d3d3dfac064..97340de57ca 100644 --- a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json @@ -33,10 +33,10 @@ "======== Resolving module '@foo/bar' from '/node_modules/a/index.d.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", - "'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' does not have a 'main' field.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/index.d.ts@1.2.3'.", "File '/node_modules/a/node_modules/@foo/bar.ts' does not exist.", "File '/node_modules/a/node_modules/@foo/bar.tsx' does not exist.", diff --git a/tests/baselines/reference/library-reference-10.trace.json b/tests/baselines/reference/library-reference-10.trace.json index d24bc21f283..3e6cf4432ea 100644 --- a/tests/baselines/reference/library-reference-10.trace.json +++ b/tests/baselines/reference/library-reference-10.trace.json @@ -1,18 +1,20 @@ [ "======== Resolving type reference directive 'jquery', containing file '/foo/consumer.ts', root directory './types'. ========", "Resolving with primary search path './types'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at './types/jquery/package.json'.", + "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.", "File 'types/jquery/jquery.d.ts' exist - use it as a name resolution result.", "Resolving real path for 'types/jquery/jquery.d.ts', result '/foo/types/jquery/jquery.d.ts'.", "======== Type reference directive 'jquery' was successfully resolved to '/foo/types/jquery/jquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'jquery', containing file '/foo/__inferred type names__.ts', root directory './types'. ========", "Resolving with primary search path './types'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at './types/jquery/package.json'.", + "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'jquery.d.ts' that references 'types/jquery/jquery.d.ts'.", "File 'types/jquery/jquery.d.ts' exist - use it as a name resolution result.", "Resolving real path for 'types/jquery/jquery.d.ts', result '/foo/types/jquery/jquery.d.ts'.", diff --git a/tests/baselines/reference/library-reference-11.trace.json b/tests/baselines/reference/library-reference-11.trace.json index 5b2d6695356..b5e324d8c36 100644 --- a/tests/baselines/reference/library-reference-11.trace.json +++ b/tests/baselines/reference/library-reference-11.trace.json @@ -3,8 +3,8 @@ "Root directory cannot be determined, skipping primary search paths.", "Looking up in 'node_modules' folder, initial location '/a/b'.", "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/a/node_modules/jquery/jquery.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/a/node_modules/jquery/package.json'.", "File '/a/node_modules/jquery.d.ts' does not exist.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/a/node_modules/jquery/jquery.d.ts'.", diff --git a/tests/baselines/reference/library-reference-12.trace.json b/tests/baselines/reference/library-reference-12.trace.json index f6c1aef4811..1421f1501d9 100644 --- a/tests/baselines/reference/library-reference-12.trace.json +++ b/tests/baselines/reference/library-reference-12.trace.json @@ -3,9 +3,9 @@ "Root directory cannot be determined, skipping primary search paths.", "Looking up in 'node_modules' folder, initial location '/a/b'.", "Directory '/a/b/node_modules' does not exist, skipping all lookups in it.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'dist/jquery.d.ts' that references '/a/node_modules/jquery/dist/jquery.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/a/node_modules/jquery/package.json'.", "File '/a/node_modules/jquery.d.ts' does not exist.", "'package.json' does not have a 'typings' field.", diff --git a/tests/baselines/reference/library-reference-2.trace.json b/tests/baselines/reference/library-reference-2.trace.json index baef46d8995..8a13d1e6f54 100644 --- a/tests/baselines/reference/library-reference-2.trace.json +++ b/tests/baselines/reference/library-reference-2.trace.json @@ -1,10 +1,11 @@ [ "======== Resolving type reference directive 'jquery', containing file '/consumer.ts', root directory '/types'. ========", "Resolving with primary search path '/types'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/types/jquery/package.json'.", + "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", "File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.", @@ -12,10 +13,11 @@ "======== Type reference directive 'jquery' was successfully resolved to '/types/jquery/jquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'jquery', containing file '/test/__inferred type names__.ts', root directory '/types'. ========", "Resolving with primary search path '/types'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/types/jquery/package.json'.", + "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", "File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json index 2f743d9e200..d386774db15 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json @@ -2,10 +2,10 @@ "======== Resolving module 'normalize.css' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'normalize.css' from 'node_modules' folder, target file type 'TypeScript'.", - "'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 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/normalize.css/package.json'.", "File '/node_modules/normalize.css.ts' does not exist.", "File '/node_modules/normalize.css.tsx' does not exist.", @@ -25,10 +25,10 @@ "File '/node_modules/normalize.css/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'normalize.css' from 'node_modules' folder, target file type 'JavaScript'.", - "'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 'normalize.css' that references '/node_modules/normalize.css/normalize.css'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/normalize.css/package.json'.", "File '/node_modules/normalize.css.js' does not exist.", "File '/node_modules/normalize.css.jsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json index 06610253558..09a7bf81c98 100644 --- a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json @@ -2,9 +2,9 @@ "======== Resolving module 'foo' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.ts' does not exist.", "File '/node_modules/foo.tsx' does not exist.", @@ -27,9 +27,9 @@ "File '/node_modules/foo/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.js' does not exist.", "File '/node_modules/foo.jsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json index 2a4a1e71a4a..dbd645d9d65 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json @@ -2,9 +2,9 @@ "======== Resolving module 'foo/bar' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'types.d.ts' that references '/node_modules/foo/bar/types.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/bar/package.json'.", "File '/node_modules/foo/bar.ts' does not exist.", "File '/node_modules/foo/bar.tsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json index b54519397ab..e47dcc86b12 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json @@ -2,9 +2,9 @@ "======== Resolving module 'foo/@bar' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'types.d.ts' that references '/node_modules/foo/@bar/types.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/@bar/package.json'.", "File '/node_modules/foo/@bar.ts' does not exist.", "File '/node_modules/foo/@bar.tsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json index 389bd892d2f..a8e509ff6e8 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_scopedPackage.trace.json @@ -2,9 +2,9 @@ "======== Resolving module '@foo/bar' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' does not have a 'typings' field.", "'package.json' has 'types' field 'types.d.ts' that references '/node_modules/@foo/bar/types.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@foo/bar/package.json'.", "File '/node_modules/@foo/bar.ts' does not exist.", "File '/node_modules/@foo/bar.tsx' does not exist.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_mainFieldInSubDirectory.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_mainFieldInSubDirectory.trace.json index 84b7a4873c0..4d7ae487813 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_mainFieldInSubDirectory.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_mainFieldInSubDirectory.trace.json @@ -2,10 +2,10 @@ "======== Resolving module 'foo' from '/index.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", - "'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 'src/index.js' that references '/node_modules/foo/src/index.js'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/src/index.d.ts@1.2.3'.", "File '/node_modules/foo.ts' does not exist.", "File '/node_modules/foo.tsx' does not exist.", diff --git a/tests/baselines/reference/packageJsonMain.trace.json b/tests/baselines/reference/packageJsonMain.trace.json index 583fc96774e..1f722312e1d 100644 --- a/tests/baselines/reference/packageJsonMain.trace.json +++ b/tests/baselines/reference/packageJsonMain.trace.json @@ -2,10 +2,10 @@ "======== Resolving module 'foo' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", - "'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 'oof' that references '/node_modules/foo/oof'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.ts' does not exist.", "File '/node_modules/foo.tsx' does not exist.", @@ -24,10 +24,10 @@ "File '/node_modules/foo/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", - "'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 'oof' that references '/node_modules/foo/oof'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.js' does not exist.", "File '/node_modules/foo.jsx' does not exist.", @@ -40,10 +40,10 @@ "======== Resolving module 'bar' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'bar' from 'node_modules' folder, target file type 'TypeScript'.", - "'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 'rab.js' that references '/node_modules/bar/rab.js'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/bar/package.json'.", "File '/node_modules/bar.ts' does not exist.", "File '/node_modules/bar.tsx' does not exist.", @@ -67,10 +67,10 @@ "File '/node_modules/bar/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'bar' from 'node_modules' folder, target file type 'JavaScript'.", - "'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 'rab.js' that references '/node_modules/bar/rab.js'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/bar/package.json'.", "File '/node_modules/bar.js' does not exist.", "File '/node_modules/bar.jsx' does not exist.", @@ -81,10 +81,10 @@ "======== Resolving module 'baz' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'baz' from 'node_modules' folder, target file type 'TypeScript'.", - "'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 'zab' that references '/node_modules/baz/zab'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/baz/package.json'.", "File '/node_modules/baz.ts' does not exist.", "File '/node_modules/baz.tsx' does not exist.", @@ -105,10 +105,10 @@ "File '/node_modules/baz/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'baz' from 'node_modules' folder, target file type 'JavaScript'.", - "'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 'zab' that references '/node_modules/baz/zab'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/baz/package.json'.", "File '/node_modules/baz.js' does not exist.", "File '/node_modules/baz.jsx' does not exist.", diff --git a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json index b7d26d0f852..f2f16ec6aeb 100644 --- a/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json +++ b/tests/baselines/reference/packageJsonMain_isNonRecursive.trace.json @@ -2,10 +2,10 @@ "======== Resolving module 'foo' from '/a.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", - "'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 'oof' that references '/node_modules/foo/oof'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.ts' does not exist.", "File '/node_modules/foo.tsx' does not exist.", @@ -26,10 +26,10 @@ "File '/node_modules/foo/index.d.ts' does not exist.", "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", - "'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 'oof' that references '/node_modules/foo/oof'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/foo/package.json'.", "File '/node_modules/foo.js' does not exist.", "File '/node_modules/foo.jsx' does not exist.", diff --git a/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.js b/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.js index 75086611695..4cd606eae0e 100644 --- a/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.js +++ b/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.js @@ -43,7 +43,6 @@ exports["default"] = Form; //// [index.d.ts] -/// /// declare const Form: import("create-emotion-styled/types/react").StyledOtherComponent<{}, import("react").DetailedHTMLProps, HTMLDivElement>, any>; export default Form; diff --git a/tests/baselines/reference/typesVersions.ambientModules.js b/tests/baselines/reference/typesVersions.ambientModules.js index c7f198b8467..5dc00d8b376 100644 --- a/tests/baselines/reference/typesVersions.ambientModules.js +++ b/tests/baselines/reference/typesVersions.ambientModules.js @@ -6,7 +6,7 @@ "version": "1.0.0", "types": "index", "typesVersions": { - "3.0": "ts3.0" + "3.0": { "*" : ["ts3.0/*"] } } } diff --git a/tests/baselines/reference/typesVersions.ambientModules.trace.json b/tests/baselines/reference/typesVersions.ambientModules.trace.json index 0bf8bc16c5d..f40d37bd7c3 100644 --- a/tests/baselines/reference/typesVersions.ambientModules.trace.json +++ b/tests/baselines/reference/typesVersions.ambientModules.trace.json @@ -2,15 +2,18 @@ "======== Resolving module 'ext' from 'tests/cases/conformance/moduleResolution/main.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.", - "'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.", "'package.json' does not have a 'typings' field.", - "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index'.", - "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/index.d.ts@1.0.0'.", - "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0.ts' does not exist.", - "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0.tsx' does not exist.", - "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0.d.ts' does not exist.", + "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/index'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.", + "File 'tests/cases/conformance/moduleResolution/node_modules/ext.ts' does not exist.", + "File 'tests/cases/conformance/moduleResolution/node_modules/ext.tsx' does not exist.", + "File 'tests/cases/conformance/moduleResolution/node_modules/ext.d.ts' does not exist.", "'package.json' does not have a 'typings' field.", - "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index'.", + "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/index'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'index'.", + "Module name 'index', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/index'.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index' does not exist.", "Loading module as file / folder, candidate module location 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index', target file type 'TypeScript'.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index.ts' does not exist.", @@ -21,8 +24,11 @@ "======== Resolving module 'ext/other' from 'tests/cases/conformance/moduleResolution/main.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'ext/other' from 'node_modules' folder, target file type 'TypeScript'.", - "'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.", - "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'other'.", + "Module name 'other', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/other'.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.ts' does not exist.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.tsx' does not exist.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.d.ts' does not exist.", @@ -33,8 +39,11 @@ "Directory 'node_modules' does not exist, skipping all lookups in it.", "Directory '/node_modules' does not exist, skipping all lookups in it.", "Loading module 'ext/other' from 'node_modules' folder, target file type 'JavaScript'.", - "'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.", - "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'other'.", + "Module name 'other', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/other'.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.js' does not exist.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.jsx' does not exist.", "Directory 'tests/cases/conformance/node_modules' does not exist, skipping all lookups in it.", diff --git a/tests/baselines/reference/typesVersions.multiFile.js b/tests/baselines/reference/typesVersions.multiFile.js index 98a1331500b..0d3b91f7b13 100644 --- a/tests/baselines/reference/typesVersions.multiFile.js +++ b/tests/baselines/reference/typesVersions.multiFile.js @@ -6,7 +6,7 @@ "version": "1.0.0", "types": "index", "typesVersions": { - "3.0": "ts3.0" + "3.0": { "*" : ["ts3.0/*"] } } } diff --git a/tests/baselines/reference/typesVersions.multiFile.trace.json b/tests/baselines/reference/typesVersions.multiFile.trace.json index 2508681421b..6884322c301 100644 --- a/tests/baselines/reference/typesVersions.multiFile.trace.json +++ b/tests/baselines/reference/typesVersions.multiFile.trace.json @@ -2,15 +2,18 @@ "======== Resolving module 'ext' from 'tests/cases/conformance/moduleResolution/main.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.", - "'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.", "'package.json' does not have a 'typings' field.", - "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index'.", - "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/index.d.ts@1.0.0'.", - "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0.ts' does not exist.", - "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0.tsx' does not exist.", - "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0.d.ts' does not exist.", + "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/index'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.", + "File 'tests/cases/conformance/moduleResolution/node_modules/ext.ts' does not exist.", + "File 'tests/cases/conformance/moduleResolution/node_modules/ext.tsx' does not exist.", + "File 'tests/cases/conformance/moduleResolution/node_modules/ext.d.ts' does not exist.", "'package.json' does not have a 'typings' field.", - "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index'.", + "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/index'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'index'.", + "Module name 'index', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/index'.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index' does not exist.", "Loading module as file / folder, candidate module location 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index', target file type 'TypeScript'.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/index.ts' does not exist.", @@ -21,8 +24,11 @@ "======== Resolving module 'ext/other' from 'tests/cases/conformance/moduleResolution/main.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'ext/other' from 'node_modules' folder, target file type 'TypeScript'.", - "'package.json' has 'typesVersions['3.0']' field 'ts3.0' that references 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0'.", - "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/ts3.0/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/moduleResolution/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'other'.", + "Module name 'other', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/other'.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.ts' does not exist.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.tsx' does not exist.", "File 'tests/cases/conformance/moduleResolution/node_modules/ext/ts3.0/other.d.ts' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.js b/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.js new file mode 100644 index 00000000000..a226df8e873 --- /dev/null +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.js @@ -0,0 +1,51 @@ +//// [tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.ambient.ts] //// + +//// [package.json] +{ + "name": "ext", + "version": "1.0.0", + "types": "index", + "typesVersions": { + "3.0": { "*" : ["ts3.0/*"] } + } +} + +//// [index.d.ts] +declare module "ext" { + export interface A {} + export function fa(): A; +} +declare module "ext/other" { + export interface B {} + export function fb(): B; +} +//// [index.d.ts] +declare module "ext" { + export interface A {} + export function fa(): A; +} +declare module "ext/other" { + export interface B {} + export function fb(): B; +} + +//// [main.ts] +import { fa } from "ext"; +import { fb } from "ext/other"; + +export const va = fa(); +export const vb = fb(); + + +//// [main.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const ext_1 = require("ext"); +const other_1 = require("ext/other"); +exports.va = ext_1.fa(); +exports.vb = other_1.fb(); + + +//// [main.d.ts] +export declare const va: import("ext").A; +export declare const vb: import("ext/other").B; diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.symbols b/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.symbols new file mode 100644 index 00000000000..15d1718cce7 --- /dev/null +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.symbols @@ -0,0 +1,37 @@ +=== tests/cases/conformance/declarationEmit/main.ts === +import { fa } from "ext"; +>fa : Symbol(fa, Decl(main.ts, 0, 8)) + +import { fb } from "ext/other"; +>fb : Symbol(fb, Decl(main.ts, 1, 8)) + +export const va = fa(); +>va : Symbol(va, Decl(main.ts, 3, 12)) +>fa : Symbol(fa, Decl(main.ts, 0, 8)) + +export const vb = fb(); +>vb : Symbol(vb, Decl(main.ts, 4, 12)) +>fb : Symbol(fb, Decl(main.ts, 1, 8)) + +=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts === +declare module "ext" { +>"ext" : Symbol("ext", Decl(index.d.ts, 0, 0)) + + export interface A {} +>A : Symbol(A, Decl(index.d.ts, 0, 22)) + + export function fa(): A; +>fa : Symbol(fa, Decl(index.d.ts, 1, 25)) +>A : Symbol(A, Decl(index.d.ts, 0, 22)) +} +declare module "ext/other" { +>"ext/other" : Symbol("ext/other", Decl(index.d.ts, 3, 1)) + + export interface B {} +>B : Symbol(B, Decl(index.d.ts, 4, 28)) + + export function fb(): B; +>fb : Symbol(fb, Decl(index.d.ts, 5, 25)) +>B : Symbol(B, Decl(index.d.ts, 4, 28)) +} + diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.trace.json b/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.trace.json new file mode 100644 index 00000000000..f973d37cd58 --- /dev/null +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.trace.json @@ -0,0 +1,55 @@ +[ + "======== Resolving module 'ext' from 'tests/cases/conformance/declarationEmit/main.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext.ts' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext.tsx' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'index'.", + "Module name 'index', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/index'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index' does not exist.", + "Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index', target file type 'TypeScript'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.ts' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.tsx' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts'.", + "======== Module name 'ext' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts'. ========", + "======== Resolving module 'ext/other' from 'tests/cases/conformance/declarationEmit/main.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'ext/other' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'other'.", + "Module name 'other', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/other'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.ts' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.tsx' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.d.ts' does not exist.", + "Directory 'tests/cases/conformance/declarationEmit/node_modules/@types' does not exist, skipping all lookups in it.", + "Directory 'tests/cases/conformance/node_modules' does not exist, skipping all lookups in it.", + "Directory 'tests/cases/node_modules' does not exist, skipping all lookups in it.", + "Directory 'tests/node_modules' does not exist, skipping all lookups in it.", + "Directory 'node_modules' does not exist, skipping all lookups in it.", + "Directory '/node_modules' does not exist, skipping all lookups in it.", + "Loading module 'ext/other' from 'node_modules' folder, target file type 'JavaScript'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'other'.", + "Module name 'other', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/other'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.js' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.jsx' does not exist.", + "Directory 'tests/cases/conformance/node_modules' does not exist, skipping all lookups in it.", + "Directory 'tests/cases/node_modules' does not exist, skipping all lookups in it.", + "Directory 'tests/node_modules' does not exist, skipping all lookups in it.", + "Directory 'node_modules' does not exist, skipping all lookups in it.", + "Directory '/node_modules' does not exist, skipping all lookups in it.", + "======== Module name 'ext/other' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.types b/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.types new file mode 100644 index 00000000000..9f47ca9750c --- /dev/null +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.ambient.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/declarationEmit/main.ts === +import { fa } from "ext"; +>fa : () => import("ext").A + +import { fb } from "ext/other"; +>fb : () => import("ext/other").B + +export const va = fa(); +>va : import("ext").A +>fa() : import("ext").A +>fa : () => import("ext").A + +export const vb = fb(); +>vb : import("ext/other").B +>fb() : import("ext/other").B +>fb : () => import("ext/other").B + +=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts === +declare module "ext" { +>"ext" : typeof import("ext") + + export interface A {} + export function fa(): A; +>fa : () => A +} +declare module "ext/other" { +>"ext/other" : typeof import("ext/other") + + export interface B {} + export function fb(): B; +>fb : () => B +} + diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.js b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.js new file mode 100644 index 00000000000..4a1edf5c97e --- /dev/null +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.js @@ -0,0 +1,48 @@ +//// [tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.multiFile.ts] //// + +//// [package.json] +{ + "name": "ext", + "version": "1.0.0", + "types": "index", + "typesVersions": { + "3.0": { "*" : ["ts3.0/*"] } + } +} + +//// [index.d.ts] +export interface A {} +export function fa(): A; + +//// [other.d.ts] +export interface B {} +export function fb(): B; + +//// [index.d.ts] +export interface A {} +export function fa(): A; + +//// [other.d.ts] +export interface B {} +export function fb(): B; + +//// [main.ts] +import { fa } from "ext"; +import { fb } from "ext/other"; + +export const va = fa(); +export const vb = fb(); + + +//// [main.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const ext_1 = require("ext"); +const other_1 = require("ext/other"); +exports.va = ext_1.fa(); +exports.vb = other_1.fb(); + + +//// [main.d.ts] +export declare const va: import("ext").A; +export declare const vb: import("ext/other").B; diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.symbols b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.symbols new file mode 100644 index 00000000000..e5db0491541 --- /dev/null +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.symbols @@ -0,0 +1,47 @@ +=== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts === +export interface A {} +>A : Symbol(A, Decl(index.d.ts, 0, 0)) + +export function fa(): A; +>fa : Symbol(fa, Decl(index.d.ts, 0, 21)) +>A : Symbol(A, Decl(index.d.ts, 0, 0)) + +=== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts === +export interface B {} +>B : Symbol(B, Decl(other.d.ts, 0, 0)) + +export function fb(): B; +>fb : Symbol(fb, Decl(other.d.ts, 0, 21)) +>B : Symbol(B, Decl(other.d.ts, 0, 0)) + +=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts === +export interface A {} +>A : Symbol(A, Decl(index.d.ts, 0, 0)) + +export function fa(): A; +>fa : Symbol(fa, Decl(index.d.ts, 0, 21)) +>A : Symbol(A, Decl(index.d.ts, 0, 0)) + +=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.d.ts === +export interface B {} +>B : Symbol(B, Decl(other.d.ts, 0, 0)) + +export function fb(): B; +>fb : Symbol(fb, Decl(other.d.ts, 0, 21)) +>B : Symbol(B, Decl(other.d.ts, 0, 0)) + +=== tests/cases/conformance/declarationEmit/main.ts === +import { fa } from "ext"; +>fa : Symbol(fa, Decl(main.ts, 0, 8)) + +import { fb } from "ext/other"; +>fb : Symbol(fb, Decl(main.ts, 1, 8)) + +export const va = fa(); +>va : Symbol(va, Decl(main.ts, 3, 12)) +>fa : Symbol(fa, Decl(main.ts, 0, 8)) + +export const vb = fb(); +>vb : Symbol(vb, Decl(main.ts, 4, 12)) +>fb : Symbol(fb, Decl(main.ts, 1, 8)) + diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.trace.json b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.trace.json new file mode 100644 index 00000000000..0296a58b896 --- /dev/null +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.trace.json @@ -0,0 +1,37 @@ +[ + "======== Resolving module 'ext' from 'tests/cases/conformance/declarationEmit/main.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'ext' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/index.d.ts@1.0.0'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext.ts' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext.tsx' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'index' that references 'tests/cases/conformance/declarationEmit/node_modules/ext/index'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'index'.", + "Module name 'index', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/index'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index' does not exist.", + "Loading module as file / folder, candidate module location 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index', target file type 'TypeScript'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.ts' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.tsx' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts'.", + "======== Module name 'ext' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts'. ========", + "======== Resolving module 'ext/other' from 'tests/cases/conformance/declarationEmit/main.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'ext/other' from 'node_modules' folder, target file type 'TypeScript'.", + "'package.json' has a 'typesVersions' field with version-specific path mappings.", + "Found 'package.json' at 'tests/cases/conformance/declarationEmit/node_modules/ext/package.json'. Package ID is 'ext/other/index.d.ts@1.0.0'.", + "'package.json' has a 'typesVersions' entry '3.0' that matches compiler version '3.1', looking for a pattern to match module name 'other'.", + "Module name 'other', matched pattern '*'.", + "Trying substitution 'ts3.0/*', candidate module location: 'ts3.0/other'.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.ts' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.tsx' does not exist.", + "File 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.d.ts' exist - use it as a name resolution result.", + "Resolving real path for 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.d.ts', result 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.d.ts'.", + "======== Module name 'ext/other' was successfully resolved to 'tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.types b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.types new file mode 100644 index 00000000000..73721bafec1 --- /dev/null +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFile.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/declarationEmit/node_modules/ext/index.d.ts === +export interface A {} +export function fa(): A; +>fa : () => A + +=== tests/cases/conformance/declarationEmit/node_modules/ext/other.d.ts === +export interface B {} +export function fb(): B; +>fb : () => B + +=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index.d.ts === +export interface A {} +export function fa(): A; +>fa : () => A + +=== tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other.d.ts === +export interface B {} +export function fb(): B; +>fb : () => B + +=== tests/cases/conformance/declarationEmit/main.ts === +import { fa } from "ext"; +>fa : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index").A + +import { fb } from "ext/other"; +>fb : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other").B + +export const va = fa(); +>va : import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index").A +>fa() : import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index").A +>fa : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/index").A + +export const vb = fb(); +>vb : import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other").B +>fb() : import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other").B +>fb : () => import("tests/cases/conformance/declarationEmit/node_modules/ext/ts3.0/other").B + diff --git a/tests/baselines/reference/typingsLookup4.trace.json b/tests/baselines/reference/typingsLookup4.trace.json index 30d0122b8fd..86b386670d6 100644 --- a/tests/baselines/reference/typingsLookup4.trace.json +++ b/tests/baselines/reference/typingsLookup4.trace.json @@ -5,8 +5,8 @@ "File '/node_modules/jquery.ts' does not exist.", "File '/node_modules/jquery.tsx' does not exist.", "File '/node_modules/jquery.d.ts' does not exist.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@types/jquery/package.json'.", "File '/node_modules/@types/jquery.d.ts' does not exist.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.", @@ -19,8 +19,8 @@ "File '/node_modules/kquery.ts' does not exist.", "File '/node_modules/kquery.tsx' does not exist.", "File '/node_modules/kquery.d.ts' does not exist.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@types/kquery/package.json'.", "File '/node_modules/@types/kquery.d.ts' does not exist.", "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", @@ -37,8 +37,8 @@ "File '/node_modules/lquery.ts' does not exist.", "File '/node_modules/lquery.tsx' does not exist.", "File '/node_modules/lquery.d.ts' does not exist.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@types/lquery/package.json'.", "File '/node_modules/@types/lquery.d.ts' does not exist.", "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", @@ -53,8 +53,8 @@ "File '/node_modules/mquery.ts' does not exist.", "File '/node_modules/mquery.tsx' does not exist.", "File '/node_modules/mquery.d.ts' does not exist.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@types/mquery/package.json'.", "File '/node_modules/@types/mquery.d.ts' does not exist.", "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", @@ -69,18 +69,20 @@ "======== Module name 'mquery' was successfully resolved to '/node_modules/@types/mquery/mquery/index.tsx'. ========", "======== Resolving type reference directive 'jquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@types/jquery/package.json'.", + "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'jquery.d.ts' that references '/node_modules/@types/jquery/jquery.d.ts'.", "File '/node_modules/@types/jquery/jquery.d.ts' exist - use it as a name resolution result.", "Resolving real path for '/node_modules/@types/jquery/jquery.d.ts', result '/node_modules/@types/jquery/jquery.d.ts'.", "======== Type reference directive 'jquery' was successfully resolved to '/node_modules/@types/jquery/jquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'kquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@types/kquery/package.json'.", + "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'kquery' that references '/node_modules/@types/kquery/kquery'.", "File '/node_modules/@types/kquery/kquery' does not exist.", "Loading module as file / folder, candidate module location '/node_modules/@types/kquery/kquery', target file type 'TypeScript'.", @@ -91,9 +93,10 @@ "======== Type reference directive 'kquery' was successfully resolved to '/node_modules/@types/kquery/kquery.d.ts', primary: true. ========", "======== Resolving type reference directive 'lquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@types/lquery/package.json'.", + "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'lquery' that references '/node_modules/@types/lquery/lquery'.", "File '/node_modules/@types/lquery/lquery' does not exist.", "Loading module as file / folder, candidate module location '/node_modules/@types/lquery/lquery', target file type 'TypeScript'.", @@ -102,9 +105,10 @@ "======== Type reference directive 'lquery' was successfully resolved to '/node_modules/@types/lquery/lquery.ts', primary: true. ========", "======== Resolving type reference directive 'mquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========", "Resolving with primary search path '/node_modules/@types'.", - "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", + "'package.json' does not have a 'typesVersions' field.", "Found 'package.json' at '/node_modules/@types/mquery/package.json'.", + "'package.json' does not have a 'typesVersions' field.", "'package.json' has 'typings' field 'mquery' that references '/node_modules/@types/mquery/mquery'.", "File '/node_modules/@types/mquery/mquery' does not exist.", "Loading module as file / folder, candidate module location '/node_modules/@types/mquery/mquery', target file type 'TypeScript'.", diff --git a/tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.ambient.ts b/tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.ambient.ts new file mode 100644 index 00000000000..27bba8e830e --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.ambient.ts @@ -0,0 +1,43 @@ +// @traceResolution: true +// @target: esnext +// @module: commonjs +// @declaration: true +// @noImplicitReferences: true +// @filename: node_modules/ext/package.json +{ + "name": "ext", + "version": "1.0.0", + "types": "index", + "typesVersions": { + "3.0": { "*" : ["ts3.0/*"] } + } +} + +// @filename: node_modules/ext/index.d.ts +declare module "ext" { + export interface A {} + export function fa(): A; +} +declare module "ext/other" { + export interface B {} + export function fb(): B; +} +// @filename: node_modules/ext/ts3.0/index.d.ts +declare module "ext" { + export interface A {} + export function fa(): A; +} +declare module "ext/other" { + export interface B {} + export function fb(): B; +} + +// @filename: main.ts +import { fa } from "ext"; +import { fb } from "ext/other"; + +export const va = fa(); +export const vb = fb(); + +// @filename: tsconfig.json +{} \ No newline at end of file diff --git a/tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.multiFile.ts b/tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.multiFile.ts new file mode 100644 index 00000000000..dd71b9b13e2 --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typesVersionsDeclarationEmit.multiFile.ts @@ -0,0 +1,39 @@ +// @traceResolution: true +// @target: esnext +// @module: commonjs +// @declaration: true +// @filename: node_modules/ext/package.json +{ + "name": "ext", + "version": "1.0.0", + "types": "index", + "typesVersions": { + "3.0": { "*" : ["ts3.0/*"] } + } +} + +// @filename: node_modules/ext/index.d.ts +export interface A {} +export function fa(): A; + +// @filename: node_modules/ext/other.d.ts +export interface B {} +export function fb(): B; + +// @filename: node_modules/ext/ts3.0/index.d.ts +export interface A {} +export function fa(): A; + +// @filename: node_modules/ext/ts3.0/other.d.ts +export interface B {} +export function fb(): B; + +// @filename: main.ts +import { fa } from "ext"; +import { fb } from "ext/other"; + +export const va = fa(); +export const vb = fb(); + +// @filename: tsconfig.json +{} \ No newline at end of file diff --git a/tests/cases/conformance/moduleResolution/typesVersions.ambientModules.ts b/tests/cases/conformance/moduleResolution/typesVersions.ambientModules.ts index 781740d96d2..ac314e0c313 100644 --- a/tests/cases/conformance/moduleResolution/typesVersions.ambientModules.ts +++ b/tests/cases/conformance/moduleResolution/typesVersions.ambientModules.ts @@ -8,7 +8,7 @@ "version": "1.0.0", "types": "index", "typesVersions": { - "3.0": "ts3.0" + "3.0": { "*" : ["ts3.0/*"] } } } diff --git a/tests/cases/conformance/moduleResolution/typesVersions.multiFile.ts b/tests/cases/conformance/moduleResolution/typesVersions.multiFile.ts index 44cf98e45c6..c9001ca2219 100644 --- a/tests/cases/conformance/moduleResolution/typesVersions.multiFile.ts +++ b/tests/cases/conformance/moduleResolution/typesVersions.multiFile.ts @@ -7,7 +7,7 @@ "version": "1.0.0", "types": "index", "typesVersions": { - "3.0": "ts3.0" + "3.0": { "*" : ["ts3.0/*"] } } } diff --git a/tests/cases/fourslash/completionForStringLiteralNonrelativeImport13.ts b/tests/cases/fourslash/completionForStringLiteralNonrelativeImport13.ts index db88a272ad5..d1e67ae9a90 100644 --- a/tests/cases/fourslash/completionForStringLiteralNonrelativeImport13.ts +++ b/tests/cases/fourslash/completionForStringLiteralNonrelativeImport13.ts @@ -8,7 +8,7 @@ //// "version": "1.0.0", //// "types": "index", //// "typesVersions": { -//// "3.0": "ts3.0" +//// "3.0": { "*" : ["ts3.0/*"] } //// } //// } @@ -31,6 +31,6 @@ verify.completions({ marker: test.markerNames(), - exact: ["index", "zzz"], + exact: ["aaa", "index", "ts3.0", "zzz"], isNewIdentifierLocation: true, });