Skip to content

Commit 564ef65

Browse files
sheetalkamattypescript-bot
authored andcommitted
If import is used in the file, prefer that import specifier over calculating new one (microsoft#42224)
* Test case where the wrong path is emitted * If import is used in the file, prefer that import specifier over calculating new one Fixes microsoft#39117 * Update Baselines and/or Applied Lint Fixes * When non-relative path is used as user preference, ignore relative paths even if they are from the existing file * Fix test * Add comment Co-authored-by: TypeScript Bot <[email protected]>
1 parent f0f23bc commit 564ef65

13 files changed

+255
-21
lines changed

Diff for: src/compiler/checker.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4395,6 +4395,7 @@ namespace ts {
43954395
getProjectReferenceRedirect: fileName => host.getProjectReferenceRedirect(fileName),
43964396
isSourceOfProjectReferenceRedirect: fileName => host.isSourceOfProjectReferenceRedirect(fileName),
43974397
fileExists: fileName => host.fileExists(fileName),
4398+
getFileIncludeReasons: () => host.getFileIncludeReasons(),
43984399
} : undefined },
43994400
encounteredError: false,
44004401
visitedTypes: undefined,

Diff for: src/compiler/emitter.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,8 @@ namespace ts {
849849
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
850850
getProgramBuildInfo: returnUndefined,
851851
getSourceFileFromReference: returnUndefined,
852-
redirectTargetsMap: createMultiMap()
852+
redirectTargetsMap: createMultiMap(),
853+
getFileIncludeReasons: notImplemented,
853854
};
854855
emitFiles(
855856
notImplementedResolver,

Diff for: src/compiler/moduleSpecifiers.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,21 @@ namespace ts.moduleSpecifiers {
104104
const info = getInfo(importingSourceFile.path, host);
105105
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol));
106106
const modulePaths = getAllModulePaths(importingSourceFile.path, moduleSourceFile.originalFileName, host);
107-
108107
const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
108+
109+
const existingSpecifier = forEach(modulePaths, modulePath => forEach(
110+
host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)),
111+
reason => {
112+
if (reason.kind !== FileIncludeKind.Import || reason.file !== importingSourceFile.path) return undefined;
113+
const specifier = getModuleNameStringLiteralAt(importingSourceFile, reason.index).text;
114+
// If the preference is for non relative and the module specifier is relative, ignore it
115+
return preferences.relativePreference !== RelativePreference.NonRelative || !pathIsRelative(specifier) ?
116+
specifier :
117+
undefined;
118+
}
119+
));
120+
if (existingSpecifier) return [existingSpecifier];
121+
109122
const importedFileIsInNodeModules = some(modulePaths, p => p.isInNodeModules);
110123

111124
// Module specifier priority:

Diff for: src/compiler/program.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,7 @@ namespace ts {
16491649
getProgramBuildInfo: () => program.getProgramBuildInfo && program.getProgramBuildInfo(),
16501650
getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref),
16511651
redirectTargetsMap,
1652+
getFileIncludeReasons: program.getFileIncludeReasons,
16521653
};
16531654
}
16541655

@@ -3968,7 +3969,8 @@ namespace ts {
39683969
return res;
39693970
}
39703971

3971-
function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: SourceFile, index: number): StringLiteralLike {
3972+
/* @internal */
3973+
export function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: SourceFile, index: number): StringLiteralLike {
39723974
if (index < imports.length) return imports[index];
39733975
let augIndex = imports.length;
39743976
for (const aug of moduleAugmentations) {

Diff for: src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7953,6 +7953,7 @@ namespace ts {
79537953
readonly redirectTargetsMap: RedirectTargetsMap;
79547954
getProjectReferenceRedirect(fileName: string): string | undefined;
79557955
isSourceOfProjectReferenceRedirect(fileName: string): boolean;
7956+
getFileIncludeReasons(): MultiMap<Path, FileIncludeReason>;
79567957
}
79577958

79587959
// Note: this used to be deprecated in our public API, but is still used internally

Diff for: src/services/utilities.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,7 @@ namespace ts {
18351835
getProjectReferenceRedirect: fileName => program.getProjectReferenceRedirect(fileName),
18361836
isSourceOfProjectReferenceRedirect: fileName => program.isSourceOfProjectReferenceRedirect(fileName),
18371837
getNearestAncestorDirectoryWithPackageJson: maybeBind(host, host.getNearestAncestorDirectoryWithPackageJson),
1838+
getFileIncludeReasons: () => program.getFileIncludeReasons(),
18381839
};
18391840
}
18401841

Diff for: src/testRunner/unittests/tsbuild/declarationEmit.ts

+39
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,44 @@ declare type MyNominal<T, Name extends string> = T & {
7575
}),
7676
commandLineArgs: ["--b", "/src/solution/tsconfig.json", "--verbose"]
7777
});
78+
79+
verifyTsc({
80+
scenario: "declarationEmit",
81+
subScenario: "when declaration file used inferred type from referenced project",
82+
fs: () => loadProjectFromFiles({
83+
"/src/tsconfig.json": JSON.stringify({
84+
compilerOptions: {
85+
composite: true,
86+
baseUrl: ".",
87+
paths: { "@fluentui/*": ["packages/*/src"] }
88+
}
89+
}),
90+
"/src/packages/pkg1/src/index.ts": Utils.dedent`
91+
export interface IThing {
92+
a: string;
93+
}
94+
export interface IThings {
95+
thing1: IThing;
96+
}`,
97+
"/src/packages/pkg1/tsconfig.json": JSON.stringify({
98+
extends: "../../tsconfig",
99+
compilerOptions: { outDir: "lib" },
100+
include: ["src"]
101+
}),
102+
"/src/packages/pkg2/src/index.ts": Utils.dedent`
103+
import { IThings } from '@fluentui/pkg1';
104+
export function fn4() {
105+
const a: IThings = { thing1: { a: 'b' } };
106+
return a.thing1;
107+
}`,
108+
"/src/packages/pkg2/tsconfig.json": JSON.stringify({
109+
extends: "../../tsconfig",
110+
compilerOptions: { outDir: "lib" },
111+
include: ["src"],
112+
references: [{ path: "../pkg1" }]
113+
}),
114+
}),
115+
commandLineArgs: ["--b", "/src/packages/pkg2/tsconfig.json", "--verbose"]
116+
});
78117
});
79118
}

Diff for: src/testRunner/unittests/tsserver/projectReferenceErrors.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ fnErr();
149149
{ line: 4, offset: 5 },
150150
{ line: 4, offset: 10 },
151151
Diagnostics.Module_0_has_no_exported_member_1,
152-
[`"../dependency/fns"`, "fnErr"],
152+
[`"../decls/fns"`, "fnErr"],
153153
"error",
154154
)
155155
],

Diff for: tests/baselines/reference/declarationEmitWithInvalidPackageJsonTypings.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@ export interface MutableRefObject<T> {
4545
current: T;
4646
}
4747
export declare function useRef<T>(current: T): MutableRefObject<T>;
48-
export declare const useCsvParser: () => MutableRefObject<typeof import("csv-parse/lib")>;
48+
export declare const useCsvParser: () => MutableRefObject<typeof import("csv-parse")>;
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(3,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
2-
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(5,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
3-
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
4-
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,30): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
5-
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(9,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
6-
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'. Did you mean to use 'import m from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
1+
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(3,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
2+
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(5,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
3+
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
4+
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,30): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
5+
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(9,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
6+
tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'. Did you mean to use 'import m from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
77

88

99
==== tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0.ts (0 errors) ====
@@ -15,24 +15,24 @@ tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27)
1515
var x1: number = defaultBinding1;
1616
import defaultBinding2, { a } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
1717
~
18-
!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
18+
!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
1919
var x1: number = defaultBinding2;
2020
import defaultBinding3, { a as b } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
2121
~
22-
!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
22+
!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
2323
var x1: number = defaultBinding3;
2424
import defaultBinding4, { x, a as y } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
2525
~
26-
!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
26+
!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
2727
~
28-
!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
28+
!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
2929
var x1: number = defaultBinding4;
3030
import defaultBinding5, { x as z, } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
3131
~
32-
!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
32+
!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
3333
var x1: number = defaultBinding5;
3434
import defaultBinding6, { m, } from "es6ImportDefaultBindingFollowedWithNamedImport1_0";
3535
~
36-
!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'. Did you mean to use 'import m from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
36+
!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'. Did you mean to use 'import m from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead?
3737
var x1: number = defaultBinding6;
3838

0 commit comments

Comments
 (0)