Try file if matched pattern specifies the extension instead of all the time (#42246)

* Test case for path mapping with extension

* Try file if matched pattern specifies the extension instead of all the time
Fixes #39743
This commit is contained in:
Sheetal Nandi 2021-01-08 12:03:29 -08:00 committed by GitHub
parent 055f363fba
commit d36df0dda5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 384 additions and 7 deletions

View file

@ -1377,7 +1377,7 @@ namespace ts {
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);
const extension = tryGetExtensionFromPath(subst);
if (extension !== undefined) {
const path = tryFile(candidate, onlyRecordFailures, state);
if (path !== undefined) {

View file

@ -0,0 +1,55 @@
error TS6504: File '/node_modules/foo/lib/test.js' is a JavaScript file. Did you mean to enable the 'allowJs' option?
The file is in the program because:
Root file specified for compilation
error TS6504: File '/relative.js' is a JavaScript file. Did you mean to enable the 'allowJs' option?
The file is in the program because:
Matched by include pattern '**/*' in '/tsconfig.json'
!!! error TS6504: File '/node_modules/foo/lib/test.js' is a JavaScript file. Did you mean to enable the 'allowJs' option?
!!! error TS6504: The file is in the program because:
!!! error TS6504: Root file specified for compilation
!!! error TS6504: File '/relative.js' is a JavaScript file. Did you mean to enable the 'allowJs' option?
!!! error TS6504: The file is in the program because:
!!! error TS6504: Matched by include pattern '**/*' in '/tsconfig.json'
==== /tsconfig.json (0 errors) ====
{
"compilerOptions": {
"outDir": "lib",
"target": "ES6",
"module": "ES6",
"baseUrl": "/",
"moduleResolution": "Node",
"noImplicitAny": true,
"traceResolution": true,
"paths": {
"foo/*": ["node_modules/foo/lib/*"]
}
}
}
==== /node_modules/foo/lib/test.js (0 errors) ====
export function test() {
console.log("test");
}
==== /node_modules/foo/lib/test.d.ts (0 errors) ====
export declare function test(): void;
==== /relative.js (0 errors) ====
export function relative() {
console.log("test");
}
==== /relative.d.ts (0 errors) ====
export declare function relative(): void;
==== /test.ts (0 errors) ====
import { test } from "foo/test.js";
import { test as test2 } from "foo/test";
import { relative } from "./relative.js";
import { relative as relative2 } from "./relative";

View file

@ -0,0 +1,30 @@
//// [tests/cases/compiler/moduleResolutionWithExtensions_withPaths.ts] ////
//// [test.js]
export function test() {
console.log("test");
}
//// [test.d.ts]
export declare function test(): void;
//// [relative.js]
export function relative() {
console.log("test");
}
//// [relative.d.ts]
export declare function relative(): void;
//// [test.ts]
import { test } from "foo/test.js";
import { test as test2 } from "foo/test";
import { relative } from "./relative.js";
import { relative as relative2 } from "./relative";
//// [test.js]
export {};

View file

@ -0,0 +1,26 @@
=== /node_modules/foo/lib/test.d.ts ===
export declare function test(): void;
>test : Symbol(test, Decl(test.d.ts, 0, 0))
=== /relative.d.ts ===
export declare function relative(): void;
>relative : Symbol(relative, Decl(relative.d.ts, 0, 0))
=== /test.ts ===
import { test } from "foo/test.js";
>test : Symbol(test, Decl(test.ts, 0, 8))
import { test as test2 } from "foo/test";
>test : Symbol(test, Decl(test.d.ts, 0, 0))
>test2 : Symbol(test2, Decl(test.ts, 1, 8))
import { relative } from "./relative.js";
>relative : Symbol(relative, Decl(test.ts, 2, 8))
import { relative as relative2 } from "./relative";
>relative : Symbol(relative, Decl(relative.d.ts, 0, 0))
>relative2 : Symbol(relative2, Decl(test.ts, 3, 8))

View file

@ -0,0 +1,48 @@
[
"======== Resolving module 'foo/test.js' from '/test.ts'. ========",
"Explicitly specified module resolution kind: 'NodeJs'.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo/test.js'.",
"'paths' option is specified, looking for a pattern to match module name 'foo/test.js'.",
"Module name 'foo/test.js', matched pattern 'foo/*'.",
"Trying substitution 'node_modules/foo/lib/*', candidate module location: 'node_modules/foo/lib/test.js'.",
"Loading module as file / folder, candidate module location '/node_modules/foo/lib/test.js', target file type 'TypeScript'.",
"File '/node_modules/foo/lib/test.js.ts' does not exist.",
"File '/node_modules/foo/lib/test.js.tsx' does not exist.",
"File '/node_modules/foo/lib/test.js.d.ts' does not exist.",
"File name '/node_modules/foo/lib/test.js' has a '.js' extension - stripping it.",
"File '/node_modules/foo/lib/test.ts' does not exist.",
"File '/node_modules/foo/lib/test.tsx' does not exist.",
"File '/node_modules/foo/lib/test.d.ts' exist - use it as a name resolution result.",
"File '/node_modules/foo/package.json' does not exist.",
"======== Module name 'foo/test.js' was successfully resolved to '/node_modules/foo/lib/test.d.ts'. ========",
"======== Resolving module 'foo/test' from '/test.ts'. ========",
"Explicitly specified module resolution kind: 'NodeJs'.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo/test'.",
"'paths' option is specified, looking for a pattern to match module name 'foo/test'.",
"Module name 'foo/test', matched pattern 'foo/*'.",
"Trying substitution 'node_modules/foo/lib/*', candidate module location: 'node_modules/foo/lib/test'.",
"Loading module as file / folder, candidate module location '/node_modules/foo/lib/test', target file type 'TypeScript'.",
"File '/node_modules/foo/lib/test.ts' does not exist.",
"File '/node_modules/foo/lib/test.tsx' does not exist.",
"File '/node_modules/foo/lib/test.d.ts' exist - use it as a name resolution result.",
"File '/node_modules/foo/package.json' does not exist.",
"======== Module name 'foo/test' was successfully resolved to '/node_modules/foo/lib/test.d.ts'. ========",
"======== Resolving module './relative.js' from '/test.ts'. ========",
"Explicitly specified module resolution kind: 'NodeJs'.",
"Loading module as file / folder, candidate module location '/relative.js', target file type 'TypeScript'.",
"File '/relative.js.ts' does not exist.",
"File '/relative.js.tsx' does not exist.",
"File '/relative.js.d.ts' does not exist.",
"File name '/relative.js' has a '.js' extension - stripping it.",
"File '/relative.ts' does not exist.",
"File '/relative.tsx' does not exist.",
"File '/relative.d.ts' exist - use it as a name resolution result.",
"======== Module name './relative.js' was successfully resolved to '/relative.d.ts'. ========",
"======== Resolving module './relative' from '/test.ts'. ========",
"Explicitly specified module resolution kind: 'NodeJs'.",
"Loading module as file / folder, candidate module location '/relative', target file type 'TypeScript'.",
"File '/relative.ts' does not exist.",
"File '/relative.tsx' does not exist.",
"File '/relative.d.ts' exist - use it as a name resolution result.",
"======== Module name './relative' was successfully resolved to '/relative.d.ts'. ========"
]

View file

@ -0,0 +1,26 @@
=== /node_modules/foo/lib/test.d.ts ===
export declare function test(): void;
>test : () => void
=== /relative.d.ts ===
export declare function relative(): void;
>relative : () => void
=== /test.ts ===
import { test } from "foo/test.js";
>test : () => void
import { test as test2 } from "foo/test";
>test : () => void
>test2 : () => void
import { relative } from "./relative.js";
>relative : () => void
import { relative as relative2 } from "./relative";
>relative : () => void
>relative2 : () => void

View file

@ -5,7 +5,6 @@
"'paths' option is specified, looking for a pattern to match module name 'zone.js'.",
"Module name 'zone.js', matched pattern '*'.",
"Trying substitution 'foo/*', candidate module location: 'foo/zone.js'.",
"File '/foo/zone.js' does not exist.",
"Loading module as file / folder, candidate module location '/foo/zone.js', target file type 'TypeScript'.",
"File '/foo/zone.js.ts' does not exist.",
"File '/foo/zone.js.tsx' does not exist.",
@ -25,7 +24,6 @@
"'paths' option is specified, looking for a pattern to match module name 'zone.tsx'.",
"Module name 'zone.tsx', matched pattern '*'.",
"Trying substitution 'foo/*', candidate module location: 'foo/zone.tsx'.",
"File '/foo/zone.tsx' does not exist.",
"Loading module as file / folder, candidate module location '/foo/zone.tsx', target file type 'TypeScript'.",
"File '/foo/zone.tsx.ts' does not exist.",
"File '/foo/zone.tsx.tsx' does not exist.",

View file

@ -5,6 +5,37 @@
"'paths' option is specified, looking for a pattern to match module name 'foo/bar/foobar.js'.",
"Module name 'foo/bar/foobar.js', matched pattern '*'.",
"Trying substitution 'node_modules/*', candidate module location: 'node_modules/foo/bar/foobar.js'.",
"Loading module as file / folder, candidate module location '/node_modules/foo/bar/foobar.js', target file type 'TypeScript'.",
"File '/node_modules/foo/bar/foobar.js.ts' does not exist.",
"File '/node_modules/foo/bar/foobar.js.tsx' does not exist.",
"File '/node_modules/foo/bar/foobar.js.d.ts' does not exist.",
"File name '/node_modules/foo/bar/foobar.js' has a '.js' extension - stripping it.",
"File '/node_modules/foo/bar/foobar.ts' does not exist.",
"File '/node_modules/foo/bar/foobar.tsx' does not exist.",
"File '/node_modules/foo/bar/foobar.d.ts' does not exist.",
"Directory '/node_modules/foo/bar/foobar.js' does not exist, skipping all lookups in it.",
"Trying substitution 'src/types', candidate module location: 'src/types'.",
"Loading module as file / folder, candidate module location '/src/types', target file type 'TypeScript'.",
"Loading module 'foo/bar/foobar.js' from 'node_modules' folder, target file type 'TypeScript'.",
"File '/node_modules/foo/package.json' does not exist.",
"File '/node_modules/foo/bar/foobar.js.ts' does not exist.",
"File '/node_modules/foo/bar/foobar.js.tsx' does not exist.",
"File '/node_modules/foo/bar/foobar.js.d.ts' does not exist.",
"File name '/node_modules/foo/bar/foobar.js' has a '.js' extension - stripping it.",
"File '/node_modules/foo/bar/foobar.ts' does not exist.",
"File '/node_modules/foo/bar/foobar.tsx' does not exist.",
"File '/node_modules/foo/bar/foobar.d.ts' does not exist.",
"Directory '/node_modules/@types' does not exist, skipping all lookups in it.",
"File name '/node_modules/@types/foo/bar/foobar.js' has a '.js' extension - stripping it.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo/bar/foobar.js'.",
"'paths' option is specified, looking for a pattern to match module name 'foo/bar/foobar.js'.",
"Module name 'foo/bar/foobar.js', matched pattern '*'.",
"Trying substitution 'node_modules/*', candidate module location: 'node_modules/foo/bar/foobar.js'.",
"Loading module as file / folder, candidate module location '/node_modules/foo/bar/foobar.js', target file type 'JavaScript'.",
"File '/node_modules/foo/bar/foobar.js.js' does not exist.",
"File '/node_modules/foo/bar/foobar.js.jsx' does not exist.",
"File name '/node_modules/foo/bar/foobar.js' has a '.js' extension - stripping it.",
"File '/node_modules/foo/bar/foobar.js' exist - use it as a name resolution result.",
"File '/node_modules/foo/package.json' does not exist.",
"======== Module name 'foo/bar/foobar.js' was successfully resolved to '/node_modules/foo/bar/foobar.js'. ========"
]

View file

@ -1,4 +1,4 @@
/a.ts(1,20): error TS7042: Module 'foo/bar/foobar.json' was resolved to '/node_modules/foo/bar/foobar.json', but '--resolveJsonModule' is not used.
/a.ts(1,20): error TS2732: Cannot find module 'foo/bar/foobar.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.
==== /tsconfig.json (0 errors) ====
@ -16,7 +16,7 @@
==== /a.ts (1 errors) ====
import foobar from "foo/bar/foobar.json";
~~~~~~~~~~~~~~~~~~~~~
!!! error TS7042: Module 'foo/bar/foobar.json' was resolved to '/node_modules/foo/bar/foobar.json', but '--resolveJsonModule' is not used.
!!! error TS2732: Cannot find module 'foo/bar/foobar.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.
==== /node_modules/foo/bar/foobar.json (0 errors) ====
{ "a": 10 }

View file

@ -5,6 +5,32 @@
"'paths' option is specified, looking for a pattern to match module name 'foo/bar/foobar.json'.",
"Module name 'foo/bar/foobar.json', matched pattern '*'.",
"Trying substitution 'node_modules/*', candidate module location: 'node_modules/foo/bar/foobar.json'.",
"File '/node_modules/foo/bar/foobar.json' exist - use it as a name resolution result.",
"======== Module name 'foo/bar/foobar.json' was successfully resolved to '/node_modules/foo/bar/foobar.json'. ========"
"Loading module as file / folder, candidate module location '/node_modules/foo/bar/foobar.json', target file type 'TypeScript'.",
"File '/node_modules/foo/bar/foobar.json.ts' does not exist.",
"File '/node_modules/foo/bar/foobar.json.tsx' does not exist.",
"File '/node_modules/foo/bar/foobar.json.d.ts' does not exist.",
"Directory '/node_modules/foo/bar/foobar.json' does not exist, skipping all lookups in it.",
"Trying substitution 'src/types', candidate module location: 'src/types'.",
"Loading module as file / folder, candidate module location '/src/types', target file type 'TypeScript'.",
"Loading module 'foo/bar/foobar.json' from 'node_modules' folder, target file type 'TypeScript'.",
"File '/node_modules/foo/package.json' does not exist.",
"File '/node_modules/foo/bar/foobar.json.ts' does not exist.",
"File '/node_modules/foo/bar/foobar.json.tsx' does not exist.",
"File '/node_modules/foo/bar/foobar.json.d.ts' does not exist.",
"Directory '/node_modules/@types' does not exist, skipping all lookups in it.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo/bar/foobar.json'.",
"'paths' option is specified, looking for a pattern to match module name 'foo/bar/foobar.json'.",
"Module name 'foo/bar/foobar.json', matched pattern '*'.",
"Trying substitution 'node_modules/*', candidate module location: 'node_modules/foo/bar/foobar.json'.",
"Loading module as file / folder, candidate module location '/node_modules/foo/bar/foobar.json', target file type 'JavaScript'.",
"File '/node_modules/foo/bar/foobar.json.js' does not exist.",
"File '/node_modules/foo/bar/foobar.json.jsx' does not exist.",
"Directory '/node_modules/foo/bar/foobar.json' does not exist, skipping all lookups in it.",
"Trying substitution 'src/types', candidate module location: 'src/types'.",
"Loading module as file / folder, candidate module location '/src/types', target file type 'JavaScript'.",
"Loading module 'foo/bar/foobar.json' from 'node_modules' folder, target file type 'JavaScript'.",
"File '/node_modules/foo/package.json' does not exist.",
"File '/node_modules/foo/bar/foobar.json.js' does not exist.",
"File '/node_modules/foo/bar/foobar.json.jsx' does not exist.",
"======== Module name 'foo/bar/foobar.json' was not resolved. ========"
]

View file

@ -0,0 +1,12 @@
//// [tests/cases/compiler/requireOfJsonFile_PathMapping.ts] ////
//// [foobar.json]
{ "a": 10 }
//// [a.ts]
import foobar from "foo/bar/foobar.json";
//// [/bin/a.js]
"use strict";
exports.__esModule = true;

View file

@ -0,0 +1,8 @@
=== /a.ts ===
import foobar from "foo/bar/foobar.json";
>foobar : Symbol(foobar, Decl(a.ts, 0, 6))
=== /node_modules/foo/bar/foobar.json ===
{ "a": 10 }
>"a" : Symbol("a", Decl(foobar.json, 0, 1))

View file

@ -0,0 +1,43 @@
[
"======== Resolving module 'foo/bar/foobar.json' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo/bar/foobar.json'.",
"'paths' option is specified, looking for a pattern to match module name 'foo/bar/foobar.json'.",
"Module name 'foo/bar/foobar.json', matched pattern '*'.",
"Trying substitution 'node_modules/*', candidate module location: 'node_modules/foo/bar/foobar.json'.",
"Loading module as file / folder, candidate module location '/node_modules/foo/bar/foobar.json', target file type 'TypeScript'.",
"File '/node_modules/foo/bar/foobar.json.ts' does not exist.",
"File '/node_modules/foo/bar/foobar.json.tsx' does not exist.",
"File '/node_modules/foo/bar/foobar.json.d.ts' does not exist.",
"Directory '/node_modules/foo/bar/foobar.json' does not exist, skipping all lookups in it.",
"Trying substitution 'src/types', candidate module location: 'src/types'.",
"Loading module as file / folder, candidate module location '/src/types', target file type 'TypeScript'.",
"Loading module 'foo/bar/foobar.json' from 'node_modules' folder, target file type 'TypeScript'.",
"File '/node_modules/foo/package.json' does not exist.",
"File '/node_modules/foo/bar/foobar.json.ts' does not exist.",
"File '/node_modules/foo/bar/foobar.json.tsx' does not exist.",
"File '/node_modules/foo/bar/foobar.json.d.ts' does not exist.",
"Directory '/node_modules/@types' does not exist, skipping all lookups in it.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo/bar/foobar.json'.",
"'paths' option is specified, looking for a pattern to match module name 'foo/bar/foobar.json'.",
"Module name 'foo/bar/foobar.json', matched pattern '*'.",
"Trying substitution 'node_modules/*', candidate module location: 'node_modules/foo/bar/foobar.json'.",
"Loading module as file / folder, candidate module location '/node_modules/foo/bar/foobar.json', target file type 'JavaScript'.",
"File '/node_modules/foo/bar/foobar.json.js' does not exist.",
"File '/node_modules/foo/bar/foobar.json.jsx' does not exist.",
"Directory '/node_modules/foo/bar/foobar.json' does not exist, skipping all lookups in it.",
"Trying substitution 'src/types', candidate module location: 'src/types'.",
"Loading module as file / folder, candidate module location '/src/types', target file type 'JavaScript'.",
"Loading module 'foo/bar/foobar.json' from 'node_modules' folder, target file type 'JavaScript'.",
"File '/node_modules/foo/package.json' does not exist.",
"File '/node_modules/foo/bar/foobar.json.js' does not exist.",
"File '/node_modules/foo/bar/foobar.json.jsx' does not exist.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo/bar/foobar.json'.",
"'paths' option is specified, looking for a pattern to match module name 'foo/bar/foobar.json'.",
"Module name 'foo/bar/foobar.json', matched pattern '*'.",
"Trying substitution 'node_modules/*', candidate module location: 'node_modules/foo/bar/foobar.json'.",
"Loading module as file / folder, candidate module location '/node_modules/foo/bar/foobar.json', target file type 'Json'.",
"File '/node_modules/foo/bar/foobar.json' exist - use it as a name resolution result.",
"File '/node_modules/foo/package.json' does not exist.",
"======== Module name 'foo/bar/foobar.json' was successfully resolved to '/node_modules/foo/bar/foobar.json'. ========"
]

View file

@ -0,0 +1,10 @@
=== /a.ts ===
import foobar from "foo/bar/foobar.json";
>foobar : { a: number; }
=== /node_modules/foo/bar/foobar.json ===
{ "a": 10 }
>{ "a": 10 } : { a: number; }
>"a" : number
>10 : 10

View file

@ -0,0 +1,40 @@
// @filename: /tsconfig.json
{
"compilerOptions": {
"outDir": "lib",
"target": "ES6",
"module": "ES6",
"baseUrl": "/",
"moduleResolution": "Node",
"noImplicitAny": true,
"traceResolution": true,
"paths": {
"foo/*": ["node_modules/foo/lib/*"]
}
}
}
// @filename: /node_modules/foo/lib/test.js
export function test() {
console.log("test");
}
// @filename: /node_modules/foo/lib/test.d.ts
export declare function test(): void;
// @filename: /relative.js
export function relative() {
console.log("test");
}
// @filename: /relative.d.ts
export declare function relative(): void;
// @filename: /test.ts
import { test } from "foo/test.js";
import { test as test2 } from "foo/test";
import { relative } from "./relative.js";
import { relative as relative2 } from "./relative";

View file

@ -0,0 +1,24 @@
// @noImplicitReferences: true
// @traceResolution: true
// @allowJs: true
// @esModuleInterop: true
// @fullEmitPaths: true
// @resolveJsonModule: true
// @Filename: /node_modules/foo/bar/foobar.json
{ "a": 10 }
// @Filename: /a.ts
import foobar from "foo/bar/foobar.json";
// @Filename: /tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"*": ["node_modules/*", "src/types"]
},
"allowJs": true,
"outDir": "bin"
}
}