Search for node_modules in parent directories when getting type roots.

This commit is contained in:
Andy Hanson
2016-09-01 09:25:20 -07:00
parent 38de65a0d5
commit 22ba111e66
6 changed files with 126 additions and 6 deletions

View File

@@ -8,8 +8,6 @@ namespace ts {
const emptyArray: any[] = [];
const defaultTypeRoots = ["node_modules/@types"];
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean): string {
while (true) {
const fileName = combinePaths(searchPath, "tsconfig.json");
@@ -168,7 +166,7 @@ namespace ts {
const typeReferenceExtensions = [".d.ts"];
function getEffectiveTypeRoots(options: CompilerOptions, host: ModuleResolutionHost) {
function getEffectiveTypeRoots(options: CompilerOptions, host: ModuleResolutionHost): string[] | undefined {
if (options.typeRoots) {
return options.typeRoots;
}
@@ -181,10 +179,33 @@ namespace ts {
currentDirectory = host.getCurrentDirectory();
}
if (!currentDirectory) {
return undefined;
return currentDirectory && getDefaultTypeRoots(currentDirectory, host);
}
function getDefaultTypeRoots(currentDirectory: string, host: ModuleResolutionHost): string[] | undefined {
const nodeModules = getNearestNodeModules(currentDirectory, host);
return nodeModules && [combinePaths(nodeModules, "@types")];
}
function getNearestNodeModules(currentDirectory: string, host: ModuleResolutionHost): string | undefined {
if (!host.directoryExists) {
return combinePaths(currentDirectory, "node_modules");
// And if it doesn't exist, tough.
}
while (true) {
const nodeModules = combinePaths(currentDirectory, "node_modules");
if (host.directoryExists(nodeModules)) {
return nodeModules;
}
else {
const parent = getDirectoryPath(currentDirectory);
if (parent === currentDirectory) {
return undefined;
}
currentDirectory = parent;
}
}
return map(defaultTypeRoots, d => combinePaths(currentDirectory, d));
}
/**

View File

@@ -0,0 +1,17 @@
//// [tests/cases/compiler/typeRootsFromNodeModulesInParentDirectory.ts] ////
//// [index.d.ts]
declare module "xyz" {
export const x: number;
}
//// [a.ts]
import { x } from "xyz";
x;
//// [a.js]
"use strict";
var xyz_1 = require("xyz");
xyz_1.x;

View File

@@ -0,0 +1,14 @@
=== /src/a.ts ===
import { x } from "xyz";
>x : Symbol(x, Decl(a.ts, 0, 8))
x;
>x : Symbol(x, Decl(a.ts, 0, 8))
=== /node_modules/@types/foo/index.d.ts ===
declare module "xyz" {
export const x: number;
>x : Symbol(x, Decl(index.d.ts, 2, 16))
}

View File

@@ -0,0 +1,39 @@
[
"======== Resolving module 'xyz' from '/src/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module 'xyz' from 'node_modules' folder.",
"File '/src/node_modules/xyz.ts' does not exist.",
"File '/src/node_modules/xyz.tsx' does not exist.",
"File '/src/node_modules/xyz.d.ts' does not exist.",
"File '/src/node_modules/xyz/package.json' does not exist.",
"File '/src/node_modules/xyz/index.ts' does not exist.",
"File '/src/node_modules/xyz/index.tsx' does not exist.",
"File '/src/node_modules/xyz/index.d.ts' does not exist.",
"File '/src/node_modules/@types/xyz.ts' does not exist.",
"File '/src/node_modules/@types/xyz.tsx' does not exist.",
"File '/src/node_modules/@types/xyz.d.ts' does not exist.",
"File '/src/node_modules/@types/xyz/package.json' does not exist.",
"File '/src/node_modules/@types/xyz/index.ts' does not exist.",
"File '/src/node_modules/@types/xyz/index.tsx' does not exist.",
"File '/src/node_modules/@types/xyz/index.d.ts' does not exist.",
"File '/node_modules/xyz.ts' does not exist.",
"File '/node_modules/xyz.tsx' does not exist.",
"File '/node_modules/xyz.d.ts' does not exist.",
"File '/node_modules/xyz/package.json' does not exist.",
"File '/node_modules/xyz/index.ts' does not exist.",
"File '/node_modules/xyz/index.tsx' does not exist.",
"File '/node_modules/xyz/index.d.ts' does not exist.",
"File '/node_modules/@types/xyz.ts' does not exist.",
"File '/node_modules/@types/xyz.tsx' does not exist.",
"File '/node_modules/@types/xyz.d.ts' does not exist.",
"File '/node_modules/@types/xyz/package.json' does not exist.",
"File '/node_modules/@types/xyz/index.ts' does not exist.",
"File '/node_modules/@types/xyz/index.tsx' does not exist.",
"File '/node_modules/@types/xyz/index.d.ts' does not exist.",
"======== Module name 'xyz' was not resolved. ========",
"======== Resolving type reference directive 'foo', containing file '/src/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
"Resolving with primary search path '/node_modules/@types'",
"File '/node_modules/@types/foo/package.json' does not exist.",
"File '/node_modules/@types/foo/index.d.ts' exist - use it as a name resolution result.",
"======== Type reference directive 'foo' was successfully resolved to '/node_modules/@types/foo/index.d.ts', primary: true. ========"
]

View File

@@ -0,0 +1,14 @@
=== /src/a.ts ===
import { x } from "xyz";
>x : number
x;
>x : number
=== /node_modules/@types/foo/index.d.ts ===
declare module "xyz" {
export const x: number;
>x : number
}

View File

@@ -0,0 +1,15 @@
// @noImplicitReferences: true
// @traceResolution: true
// @currentDirectory: /src
// @Filename: /node_modules/@types/foo/index.d.ts
declare module "xyz" {
export const x: number;
}
// @Filename: /src/a.ts
import { x } from "xyz";
x;
// @Filename: /src/tsconfig.json
{}