diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 47cc9c27b886b..45b69b9efc271 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5679,7 +5679,7 @@ namespace ts { specifierCompilerOptions, contextFile, moduleResolverHost, - { importModuleSpecifierPreference: isBundle ? "non-relative" : "relative", importModuleSpecifierEnding: isBundle ? "minimal" : undefined }, + { importModuleSpecifierPreference: isBundle ? "non-relative" : "project-relative", importModuleSpecifierEnding: isBundle ? "minimal" : undefined }, )); links.specifierCache ??= new Map(); links.specifierCache.set(contextFile.path, specifier); diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index ac30c5328b082..45b31154344c8 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -181,14 +181,13 @@ namespace ts.moduleSpecifiers { function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, { ending, relativePreference }: Preferences): string { const { baseUrl, paths, rootDirs } = compilerOptions; const { sourceDirectory, getCanonicalFileName } = info; - const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) || removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions); if (!baseUrl && !paths || relativePreference === RelativePreference.Relative) { return relativePath; } - const baseDirectory = getPathsBasePath(compilerOptions, host) || baseUrl!; + const baseDirectory = getNormalizedAbsolutePath(getPathsBasePath(compilerOptions, host) || baseUrl!, host.getCurrentDirectory()); const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseDirectory, getCanonicalFileName); if (!relativeToBaseUrl) { return relativePath; @@ -206,7 +205,9 @@ namespace ts.moduleSpecifiers { } if (relativePreference === RelativePreference.ExternalNonRelative) { - const projectDirectory = host.getCurrentDirectory(); + const projectDirectory = compilerOptions.configFilePath ? + toPath(getDirectoryPath(compilerOptions.configFilePath), host.getCurrentDirectory(), info.getCanonicalFileName) : + info.getCanonicalFileName(host.getCurrentDirectory()); const modulePath = toPath(moduleFileName, projectDirectory, getCanonicalFileName); const sourceIsInternal = startsWith(sourceDirectory, projectDirectory); const targetIsInternal = startsWith(modulePath, projectDirectory); @@ -446,7 +447,7 @@ namespace ts.moduleSpecifiers { startsWith(relativeToBaseUrl, prefix) && endsWith(relativeToBaseUrl, suffix) || !suffix && relativeToBaseUrl === removeTrailingDirectorySeparator(prefix)) { - const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); + const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length - prefix.length); return key.replace("*", matchedStar); } } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 260da092081a7..5a56075706720 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -372,9 +372,7 @@ namespace ts { if (declFileName) { const specifier = moduleSpecifiers.getModuleSpecifier( - // We pathify the baseUrl since we pathify the other paths here, so we can still easily check if the other paths are within the baseUrl - // TODO: Should we _always_ be pathifying the baseUrl as we read it in? - { ...options, baseUrl: options.baseUrl && toPath(options.baseUrl, host.getCurrentDirectory(), host.getCanonicalFileName) }, + options, currentSourceFile, toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName), toPath(declFileName, host.getCurrentDirectory(), host.getCanonicalFileName), diff --git a/tests/baselines/reference/declarationEmitPathMappingMonorepo2.js b/tests/baselines/reference/declarationEmitPathMappingMonorepo2.js new file mode 100644 index 0000000000000..e86ccf67a5b32 --- /dev/null +++ b/tests/baselines/reference/declarationEmitPathMappingMonorepo2.js @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/declarationEmitPathMappingMonorepo2.ts] //// + +//// [index.d.ts] +export * from "./utils"; +export { default as SvgIcon } from "./SvgIcon"; + +//// [SvgIcon.d.ts] +import { StyledComponentProps } from "@ts-bug/styles"; +export interface SvgIconProps extends StyledComponentProps<"root"> { + children?: string[]; +} +export interface SomeInterface { + myProp: string; +} +declare const SvgIcon: SomeInterface; +export default SvgIcon; + +//// [utils.d.ts] +import SvgIcon from "./SvgIcon"; +export function createSvgIcon(path: string, displayName: string): typeof SvgIcon; + +//// [index.d.ts] +export interface StyledComponentProps { + classes?: Record; +} + +//// [index.ts] +import { createSvgIcon } from "@ts-bug/core/utils"; +export default createSvgIcon("Hello", "ArrowLeft"); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var utils_1 = require("@ts-bug/core/utils"); +exports["default"] = (0, utils_1.createSvgIcon)("Hello", "ArrowLeft"); + + +//// [index.d.ts] +declare const _default: import("@ts-bug/core/SvgIcon").SomeInterface; +export default _default; diff --git a/tests/baselines/reference/declarationEmitPathMappingMonorepo2.symbols b/tests/baselines/reference/declarationEmitPathMappingMonorepo2.symbols new file mode 100644 index 0000000000000..96599b2d838c6 --- /dev/null +++ b/tests/baselines/reference/declarationEmitPathMappingMonorepo2.symbols @@ -0,0 +1,58 @@ +=== tests/cases/compiler/packages/core/src/index.d.ts === +export * from "./utils"; +export { default as SvgIcon } from "./SvgIcon"; +>default : Symbol(default, Decl(SvgIcon.d.ts, 7, 37)) +>SvgIcon : Symbol(SvgIcon, Decl(index.d.ts, 1, 8)) + +=== tests/cases/compiler/packages/core/src/SvgIcon.d.ts === +import { StyledComponentProps } from "@ts-bug/styles"; +>StyledComponentProps : Symbol(StyledComponentProps, Decl(SvgIcon.d.ts, 0, 8)) + +export interface SvgIconProps extends StyledComponentProps<"root"> { +>SvgIconProps : Symbol(SvgIconProps, Decl(SvgIcon.d.ts, 0, 54)) +>StyledComponentProps : Symbol(StyledComponentProps, Decl(SvgIcon.d.ts, 0, 8)) + + children?: string[]; +>children : Symbol(SvgIconProps.children, Decl(SvgIcon.d.ts, 1, 68)) +} +export interface SomeInterface { +>SomeInterface : Symbol(SomeInterface, Decl(SvgIcon.d.ts, 3, 1)) + + myProp: string; +>myProp : Symbol(SomeInterface.myProp, Decl(SvgIcon.d.ts, 4, 32)) +} +declare const SvgIcon: SomeInterface; +>SvgIcon : Symbol(SvgIcon, Decl(SvgIcon.d.ts, 7, 13)) +>SomeInterface : Symbol(SomeInterface, Decl(SvgIcon.d.ts, 3, 1)) + +export default SvgIcon; +>SvgIcon : Symbol(SvgIcon, Decl(SvgIcon.d.ts, 7, 13)) + +=== tests/cases/compiler/packages/core/src/utils.d.ts === +import SvgIcon from "./SvgIcon"; +>SvgIcon : Symbol(SvgIcon, Decl(utils.d.ts, 0, 6)) + +export function createSvgIcon(path: string, displayName: string): typeof SvgIcon; +>createSvgIcon : Symbol(createSvgIcon, Decl(utils.d.ts, 0, 32)) +>path : Symbol(path, Decl(utils.d.ts, 1, 30)) +>displayName : Symbol(displayName, Decl(utils.d.ts, 1, 43)) +>SvgIcon : Symbol(SvgIcon, Decl(utils.d.ts, 0, 6)) + +=== tests/cases/compiler/packages/styles/src/index.d.ts === +export interface StyledComponentProps { +>StyledComponentProps : Symbol(StyledComponentProps, Decl(index.d.ts, 0, 0)) +>ClassKey : Symbol(ClassKey, Decl(index.d.ts, 0, 38)) + + classes?: Record; +>classes : Symbol(StyledComponentProps.classes, Decl(index.d.ts, 0, 64)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>ClassKey : Symbol(ClassKey, Decl(index.d.ts, 0, 38)) +} + +=== tests/cases/compiler/packages/lab/src/index.ts === +import { createSvgIcon } from "@ts-bug/core/utils"; +>createSvgIcon : Symbol(createSvgIcon, Decl(index.ts, 0, 8)) + +export default createSvgIcon("Hello", "ArrowLeft"); +>createSvgIcon : Symbol(createSvgIcon, Decl(index.ts, 0, 8)) + diff --git a/tests/baselines/reference/declarationEmitPathMappingMonorepo2.types b/tests/baselines/reference/declarationEmitPathMappingMonorepo2.types new file mode 100644 index 0000000000000..120f52b227d4b --- /dev/null +++ b/tests/baselines/reference/declarationEmitPathMappingMonorepo2.types @@ -0,0 +1,50 @@ +=== tests/cases/compiler/packages/core/src/index.d.ts === +export * from "./utils"; +export { default as SvgIcon } from "./SvgIcon"; +>default : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface +>SvgIcon : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface + +=== tests/cases/compiler/packages/core/src/SvgIcon.d.ts === +import { StyledComponentProps } from "@ts-bug/styles"; +>StyledComponentProps : any + +export interface SvgIconProps extends StyledComponentProps<"root"> { + children?: string[]; +>children : string[] +} +export interface SomeInterface { + myProp: string; +>myProp : string +} +declare const SvgIcon: SomeInterface; +>SvgIcon : SomeInterface + +export default SvgIcon; +>SvgIcon : SomeInterface + +=== tests/cases/compiler/packages/core/src/utils.d.ts === +import SvgIcon from "./SvgIcon"; +>SvgIcon : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface + +export function createSvgIcon(path: string, displayName: string): typeof SvgIcon; +>createSvgIcon : (path: string, displayName: string) => typeof SvgIcon +>path : string +>displayName : string +>SvgIcon : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface + +=== tests/cases/compiler/packages/styles/src/index.d.ts === +export interface StyledComponentProps { + classes?: Record; +>classes : Record +} + +=== tests/cases/compiler/packages/lab/src/index.ts === +import { createSvgIcon } from "@ts-bug/core/utils"; +>createSvgIcon : (path: string, displayName: string) => import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface + +export default createSvgIcon("Hello", "ArrowLeft"); +>createSvgIcon("Hello", "ArrowLeft") : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface +>createSvgIcon : (path: string, displayName: string) => import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface +>"Hello" : "Hello" +>"ArrowLeft" : "ArrowLeft" + diff --git a/tests/cases/compiler/declarationEmitPathMappingMonorepo2.ts b/tests/cases/compiler/declarationEmitPathMappingMonorepo2.ts new file mode 100644 index 0000000000000..aab1a00e143ec --- /dev/null +++ b/tests/cases/compiler/declarationEmitPathMappingMonorepo2.ts @@ -0,0 +1,44 @@ +// @filename: packages/core/src/index.d.ts +export * from "./utils"; +export { default as SvgIcon } from "./SvgIcon"; + +// @filename: packages/core/src/SvgIcon.d.ts +import { StyledComponentProps } from "@ts-bug/styles"; +export interface SvgIconProps extends StyledComponentProps<"root"> { + children?: string[]; +} +export interface SomeInterface { + myProp: string; +} +declare const SvgIcon: SomeInterface; +export default SvgIcon; + +// @filename: packages/core/src/utils.d.ts +import SvgIcon from "./SvgIcon"; +export function createSvgIcon(path: string, displayName: string): typeof SvgIcon; + +// @filename: packages/styles/src/index.d.ts +export interface StyledComponentProps { + classes?: Record; +} + +// @filename: packages/lab/src/index.ts +import { createSvgIcon } from "@ts-bug/core/utils"; +export default createSvgIcon("Hello", "ArrowLeft"); + +// @filename: packages/lab/tsconfig.json +{ + "compilerOptions": { + "outDir": "dist", + "declaration": true, + "baseUrl": "../", + "paths": { + "@ts-bug/core": ["./core/src"], + "@ts-bug/core/*": ["./core/src/*"], + "@ts-bug/lab": ["./lab/src"], + "@ts-bug/lab/*": ["./lab/src/*"], + "@ts-bug/styles": ["./styles/src"], + "@ts-bug/styles/*": ["./styles/src/*"] + } + } +} \ No newline at end of file