Skip to content

Commit 54096bd

Browse files
authored
Use project relative preference for declaration emit (#42232)
* Test where relative import isnt ideal in the declaration emit * use project relative preference for declaration emit Fixes #39117 * Fix incorrect path matching when calculating module specifier * Use correct baseUrl for the module specifier
1 parent c96b472 commit 54096bd

7 files changed

+200
-8
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5679,7 +5679,7 @@ namespace ts {
56795679
specifierCompilerOptions,
56805680
contextFile,
56815681
moduleResolverHost,
5682-
{ importModuleSpecifierPreference: isBundle ? "non-relative" : "relative", importModuleSpecifierEnding: isBundle ? "minimal" : undefined },
5682+
{ importModuleSpecifierPreference: isBundle ? "non-relative" : "project-relative", importModuleSpecifierEnding: isBundle ? "minimal" : undefined },
56835683
));
56845684
links.specifierCache ??= new Map();
56855685
links.specifierCache.set(contextFile.path, specifier);

src/compiler/moduleSpecifiers.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,13 @@ namespace ts.moduleSpecifiers {
181181
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, { ending, relativePreference }: Preferences): string {
182182
const { baseUrl, paths, rootDirs } = compilerOptions;
183183
const { sourceDirectory, getCanonicalFileName } = info;
184-
185184
const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) ||
186185
removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
187186
if (!baseUrl && !paths || relativePreference === RelativePreference.Relative) {
188187
return relativePath;
189188
}
190189

191-
const baseDirectory = getPathsBasePath(compilerOptions, host) || baseUrl!;
190+
const baseDirectory = getNormalizedAbsolutePath(getPathsBasePath(compilerOptions, host) || baseUrl!, host.getCurrentDirectory());
192191
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseDirectory, getCanonicalFileName);
193192
if (!relativeToBaseUrl) {
194193
return relativePath;
@@ -206,7 +205,9 @@ namespace ts.moduleSpecifiers {
206205
}
207206

208207
if (relativePreference === RelativePreference.ExternalNonRelative) {
209-
const projectDirectory = host.getCurrentDirectory();
208+
const projectDirectory = compilerOptions.configFilePath ?
209+
toPath(getDirectoryPath(compilerOptions.configFilePath), host.getCurrentDirectory(), info.getCanonicalFileName) :
210+
info.getCanonicalFileName(host.getCurrentDirectory());
210211
const modulePath = toPath(moduleFileName, projectDirectory, getCanonicalFileName);
211212
const sourceIsInternal = startsWith(sourceDirectory, projectDirectory);
212213
const targetIsInternal = startsWith(modulePath, projectDirectory);
@@ -446,7 +447,7 @@ namespace ts.moduleSpecifiers {
446447
startsWith(relativeToBaseUrl, prefix) &&
447448
endsWith(relativeToBaseUrl, suffix) ||
448449
!suffix && relativeToBaseUrl === removeTrailingDirectorySeparator(prefix)) {
449-
const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length);
450+
const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length - prefix.length);
450451
return key.replace("*", matchedStar);
451452
}
452453
}

src/compiler/transformers/declarations.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,7 @@ namespace ts {
372372

373373
if (declFileName) {
374374
const specifier = moduleSpecifiers.getModuleSpecifier(
375-
// 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
376-
// TODO: Should we _always_ be pathifying the baseUrl as we read it in?
377-
{ ...options, baseUrl: options.baseUrl && toPath(options.baseUrl, host.getCurrentDirectory(), host.getCanonicalFileName) },
375+
options,
378376
currentSourceFile,
379377
toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName),
380378
toPath(declFileName, host.getCurrentDirectory(), host.getCanonicalFileName),
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//// [tests/cases/compiler/declarationEmitPathMappingMonorepo2.ts] ////
2+
3+
//// [index.d.ts]
4+
export * from "./utils";
5+
export { default as SvgIcon } from "./SvgIcon";
6+
7+
//// [SvgIcon.d.ts]
8+
import { StyledComponentProps } from "@ts-bug/styles";
9+
export interface SvgIconProps extends StyledComponentProps<"root"> {
10+
children?: string[];
11+
}
12+
export interface SomeInterface {
13+
myProp: string;
14+
}
15+
declare const SvgIcon: SomeInterface;
16+
export default SvgIcon;
17+
18+
//// [utils.d.ts]
19+
import SvgIcon from "./SvgIcon";
20+
export function createSvgIcon(path: string, displayName: string): typeof SvgIcon;
21+
22+
//// [index.d.ts]
23+
export interface StyledComponentProps<ClassKey extends string> {
24+
classes?: Record<ClassKey, string>;
25+
}
26+
27+
//// [index.ts]
28+
import { createSvgIcon } from "@ts-bug/core/utils";
29+
export default createSvgIcon("Hello", "ArrowLeft");
30+
31+
32+
//// [index.js]
33+
"use strict";
34+
exports.__esModule = true;
35+
var utils_1 = require("@ts-bug/core/utils");
36+
exports["default"] = (0, utils_1.createSvgIcon)("Hello", "ArrowLeft");
37+
38+
39+
//// [index.d.ts]
40+
declare const _default: import("@ts-bug/core/SvgIcon").SomeInterface;
41+
export default _default;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=== tests/cases/compiler/packages/core/src/index.d.ts ===
2+
export * from "./utils";
3+
export { default as SvgIcon } from "./SvgIcon";
4+
>default : Symbol(default, Decl(SvgIcon.d.ts, 7, 37))
5+
>SvgIcon : Symbol(SvgIcon, Decl(index.d.ts, 1, 8))
6+
7+
=== tests/cases/compiler/packages/core/src/SvgIcon.d.ts ===
8+
import { StyledComponentProps } from "@ts-bug/styles";
9+
>StyledComponentProps : Symbol(StyledComponentProps, Decl(SvgIcon.d.ts, 0, 8))
10+
11+
export interface SvgIconProps extends StyledComponentProps<"root"> {
12+
>SvgIconProps : Symbol(SvgIconProps, Decl(SvgIcon.d.ts, 0, 54))
13+
>StyledComponentProps : Symbol(StyledComponentProps, Decl(SvgIcon.d.ts, 0, 8))
14+
15+
children?: string[];
16+
>children : Symbol(SvgIconProps.children, Decl(SvgIcon.d.ts, 1, 68))
17+
}
18+
export interface SomeInterface {
19+
>SomeInterface : Symbol(SomeInterface, Decl(SvgIcon.d.ts, 3, 1))
20+
21+
myProp: string;
22+
>myProp : Symbol(SomeInterface.myProp, Decl(SvgIcon.d.ts, 4, 32))
23+
}
24+
declare const SvgIcon: SomeInterface;
25+
>SvgIcon : Symbol(SvgIcon, Decl(SvgIcon.d.ts, 7, 13))
26+
>SomeInterface : Symbol(SomeInterface, Decl(SvgIcon.d.ts, 3, 1))
27+
28+
export default SvgIcon;
29+
>SvgIcon : Symbol(SvgIcon, Decl(SvgIcon.d.ts, 7, 13))
30+
31+
=== tests/cases/compiler/packages/core/src/utils.d.ts ===
32+
import SvgIcon from "./SvgIcon";
33+
>SvgIcon : Symbol(SvgIcon, Decl(utils.d.ts, 0, 6))
34+
35+
export function createSvgIcon(path: string, displayName: string): typeof SvgIcon;
36+
>createSvgIcon : Symbol(createSvgIcon, Decl(utils.d.ts, 0, 32))
37+
>path : Symbol(path, Decl(utils.d.ts, 1, 30))
38+
>displayName : Symbol(displayName, Decl(utils.d.ts, 1, 43))
39+
>SvgIcon : Symbol(SvgIcon, Decl(utils.d.ts, 0, 6))
40+
41+
=== tests/cases/compiler/packages/styles/src/index.d.ts ===
42+
export interface StyledComponentProps<ClassKey extends string> {
43+
>StyledComponentProps : Symbol(StyledComponentProps, Decl(index.d.ts, 0, 0))
44+
>ClassKey : Symbol(ClassKey, Decl(index.d.ts, 0, 38))
45+
46+
classes?: Record<ClassKey, string>;
47+
>classes : Symbol(StyledComponentProps.classes, Decl(index.d.ts, 0, 64))
48+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
49+
>ClassKey : Symbol(ClassKey, Decl(index.d.ts, 0, 38))
50+
}
51+
52+
=== tests/cases/compiler/packages/lab/src/index.ts ===
53+
import { createSvgIcon } from "@ts-bug/core/utils";
54+
>createSvgIcon : Symbol(createSvgIcon, Decl(index.ts, 0, 8))
55+
56+
export default createSvgIcon("Hello", "ArrowLeft");
57+
>createSvgIcon : Symbol(createSvgIcon, Decl(index.ts, 0, 8))
58+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
=== tests/cases/compiler/packages/core/src/index.d.ts ===
2+
export * from "./utils";
3+
export { default as SvgIcon } from "./SvgIcon";
4+
>default : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface
5+
>SvgIcon : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface
6+
7+
=== tests/cases/compiler/packages/core/src/SvgIcon.d.ts ===
8+
import { StyledComponentProps } from "@ts-bug/styles";
9+
>StyledComponentProps : any
10+
11+
export interface SvgIconProps extends StyledComponentProps<"root"> {
12+
children?: string[];
13+
>children : string[]
14+
}
15+
export interface SomeInterface {
16+
myProp: string;
17+
>myProp : string
18+
}
19+
declare const SvgIcon: SomeInterface;
20+
>SvgIcon : SomeInterface
21+
22+
export default SvgIcon;
23+
>SvgIcon : SomeInterface
24+
25+
=== tests/cases/compiler/packages/core/src/utils.d.ts ===
26+
import SvgIcon from "./SvgIcon";
27+
>SvgIcon : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface
28+
29+
export function createSvgIcon(path: string, displayName: string): typeof SvgIcon;
30+
>createSvgIcon : (path: string, displayName: string) => typeof SvgIcon
31+
>path : string
32+
>displayName : string
33+
>SvgIcon : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface
34+
35+
=== tests/cases/compiler/packages/styles/src/index.d.ts ===
36+
export interface StyledComponentProps<ClassKey extends string> {
37+
classes?: Record<ClassKey, string>;
38+
>classes : Record<ClassKey, string>
39+
}
40+
41+
=== tests/cases/compiler/packages/lab/src/index.ts ===
42+
import { createSvgIcon } from "@ts-bug/core/utils";
43+
>createSvgIcon : (path: string, displayName: string) => import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface
44+
45+
export default createSvgIcon("Hello", "ArrowLeft");
46+
>createSvgIcon("Hello", "ArrowLeft") : import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface
47+
>createSvgIcon : (path: string, displayName: string) => import("tests/cases/compiler/packages/core/src/SvgIcon").SomeInterface
48+
>"Hello" : "Hello"
49+
>"ArrowLeft" : "ArrowLeft"
50+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// @filename: packages/core/src/index.d.ts
2+
export * from "./utils";
3+
export { default as SvgIcon } from "./SvgIcon";
4+
5+
// @filename: packages/core/src/SvgIcon.d.ts
6+
import { StyledComponentProps } from "@ts-bug/styles";
7+
export interface SvgIconProps extends StyledComponentProps<"root"> {
8+
children?: string[];
9+
}
10+
export interface SomeInterface {
11+
myProp: string;
12+
}
13+
declare const SvgIcon: SomeInterface;
14+
export default SvgIcon;
15+
16+
// @filename: packages/core/src/utils.d.ts
17+
import SvgIcon from "./SvgIcon";
18+
export function createSvgIcon(path: string, displayName: string): typeof SvgIcon;
19+
20+
// @filename: packages/styles/src/index.d.ts
21+
export interface StyledComponentProps<ClassKey extends string> {
22+
classes?: Record<ClassKey, string>;
23+
}
24+
25+
// @filename: packages/lab/src/index.ts
26+
import { createSvgIcon } from "@ts-bug/core/utils";
27+
export default createSvgIcon("Hello", "ArrowLeft");
28+
29+
// @filename: packages/lab/tsconfig.json
30+
{
31+
"compilerOptions": {
32+
"outDir": "dist",
33+
"declaration": true,
34+
"baseUrl": "../",
35+
"paths": {
36+
"@ts-bug/core": ["./core/src"],
37+
"@ts-bug/core/*": ["./core/src/*"],
38+
"@ts-bug/lab": ["./lab/src"],
39+
"@ts-bug/lab/*": ["./lab/src/*"],
40+
"@ts-bug/styles": ["./styles/src"],
41+
"@ts-bug/styles/*": ["./styles/src/*"]
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)