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
This commit is contained in:
Sheetal Nandi
2021-04-30 13:22:05 -07:00
committed by GitHub
parent c96b472e0b
commit 54096bdb96
7 changed files with 200 additions and 8 deletions

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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),

View File

@@ -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<ClassKey extends string> {
classes?: Record<ClassKey, string>;
}
//// [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;

View File

@@ -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<ClassKey extends string> {
>StyledComponentProps : Symbol(StyledComponentProps, Decl(index.d.ts, 0, 0))
>ClassKey : Symbol(ClassKey, Decl(index.d.ts, 0, 38))
classes?: Record<ClassKey, string>;
>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))

View File

@@ -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<ClassKey extends string> {
classes?: Record<ClassKey, string>;
>classes : Record<ClassKey, string>
}
=== 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"

View File

@@ -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<ClassKey extends string> {
classes?: Record<ClassKey, string>;
}
// @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/*"]
}
}
}