Merge pull request #15051 from Microsoft/at_types

Support @types module resolution from scoped packages
This commit is contained in:
Mohamed Hegazy
2017-04-17 10:08:15 -07:00
committed by GitHub
17 changed files with 226 additions and 1 deletions

View File

@@ -3185,6 +3185,10 @@
"category": "Message",
"code": 6181
},
"Scoped package detected, looking in '{0}'": {
"category": "Message",
"code": "6182"
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",

View File

@@ -954,10 +954,25 @@ namespace ts {
}
nodeModulesAtTypesExists = false;
}
return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, moduleName, nodeModulesAtTypes, nodeModulesAtTypesExists, failedLookupLocations, state);
return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, mangleScopedPackage(moduleName, state), nodeModulesAtTypes, nodeModulesAtTypesExists, failedLookupLocations, state);
}
}
/** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
function mangleScopedPackage(moduleName: string, state: ModuleResolutionState): string {
if (startsWith(moduleName, "@")) {
const replaceSlash = moduleName.replace(ts.directorySeparator, "__");
if (replaceSlash !== moduleName) {
const mangled = replaceSlash.slice(1); // Take off the "@"
if (state.traceEnabled) {
trace(state.host, Diagnostics.Scoped_package_detected_looking_in_0, mangled);
}
return mangled;
}
}
return moduleName;
}
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult<Resolved> {
const result = cache && cache.get(containingDirectory);
if (result) {

View File

@@ -0,0 +1,11 @@
//// [tests/cases/conformance/references/library-reference-scoped-packages.ts] ////
//// [index.d.ts]
export const y = 0;
//// [a.ts]
/// <reference types="@beep/boop" />
//// [a.js]
/// <reference types="@beep/boop" />

View File

@@ -0,0 +1,7 @@
=== /a.ts ===
/// <reference types="@beep/boop" />
No type information for this code.
No type information for this code.=== /node_modules/@types/beep__boop/index.d.ts ===
export const y = 0;
>y : Symbol(y, Decl(index.d.ts, 0, 12))

View File

@@ -0,0 +1,12 @@
[
"======== Resolving type reference directive '@beep/boop', containing file '/a.ts', root directory 'types'. ========",
"Resolving with primary search path 'types'.",
"Directory 'types/@beep' does not exist, skipping all lookups in it.",
"Looking up in 'node_modules' folder, initial location '/'.",
"Scoped package detected, looking in 'beep__boop'",
"File '/node_modules/@types/beep__boop.d.ts' does not exist.",
"File '/node_modules/@types/beep__boop/package.json' does not exist.",
"File '/node_modules/@types/beep__boop/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for '/node_modules/@types/beep__boop/index.d.ts', result '/node_modules/@types/beep__boop/index.d.ts'.",
"======== Type reference directive '@beep/boop' was successfully resolved to '/node_modules/@types/beep__boop/index.d.ts', primary: false. ========"
]

View File

@@ -0,0 +1,8 @@
=== /a.ts ===
/// <reference types="@beep/boop" />
No type information for this code.
No type information for this code.=== /node_modules/@types/beep__boop/index.d.ts ===
export const y = 0;
>y : 0
>0 : 0

View File

@@ -0,0 +1,20 @@
//// [tests/cases/conformance/moduleResolution/scopedPackages.ts] ////
//// [index.d.ts]
export const x: number;
//// [index.d.ts]
export const y: number;
//// [z.d.ts]
export const z: number;
//// [a.ts]
import { x } from "@cow/boy";
import { y } from "@be/bop";
import { z } from "@be/bop/e/z";
//// [a.js]
"use strict";
exports.__esModule = true;

View File

@@ -0,0 +1,22 @@
=== /a.ts ===
import { x } from "@cow/boy";
>x : Symbol(x, Decl(a.ts, 0, 8))
import { y } from "@be/bop";
>y : Symbol(y, Decl(a.ts, 1, 8))
import { z } from "@be/bop/e/z";
>z : Symbol(z, Decl(a.ts, 2, 8))
=== /node_modules/@cow/boy/index.d.ts ===
export const x: number;
>x : Symbol(x, Decl(index.d.ts, 0, 12))
=== /node_modules/@types/be__bop/index.d.ts ===
export const y: number;
>y : Symbol(y, Decl(index.d.ts, 0, 12))
=== /node_modules/@types/be__bop/e/z.d.ts ===
export const z: number;
>z : Symbol(z, Decl(z.d.ts, 0, 12))

View File

@@ -0,0 +1,30 @@
[
"======== Resolving module '@cow/boy' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module '@cow/boy' from 'node_modules' folder, target file type 'TypeScript'.",
"File '/node_modules/@cow/boy.ts' does not exist.",
"File '/node_modules/@cow/boy.tsx' does not exist.",
"File '/node_modules/@cow/boy.d.ts' does not exist.",
"File '/node_modules/@cow/boy/package.json' does not exist.",
"File '/node_modules/@cow/boy/index.ts' does not exist.",
"File '/node_modules/@cow/boy/index.tsx' does not exist.",
"File '/node_modules/@cow/boy/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for '/node_modules/@cow/boy/index.d.ts', result '/node_modules/@cow/boy/index.d.ts'.",
"======== Module name '@cow/boy' was successfully resolved to '/node_modules/@cow/boy/index.d.ts'. ========",
"======== Resolving module '@be/bop' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module '@be/bop' from 'node_modules' folder, target file type 'TypeScript'.",
"Scoped package detected, looking in 'be__bop'",
"File '/node_modules/@types/be__bop.d.ts' does not exist.",
"File '/node_modules/@types/be__bop/package.json' does not exist.",
"File '/node_modules/@types/be__bop/index.d.ts' exist - use it as a name resolution result.",
"Resolving real path for '/node_modules/@types/be__bop/index.d.ts', result '/node_modules/@types/be__bop/index.d.ts'.",
"======== Module name '@be/bop' was successfully resolved to '/node_modules/@types/be__bop/index.d.ts'. ========",
"======== Resolving module '@be/bop/e/z' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"Loading module '@be/bop/e/z' from 'node_modules' folder, target file type 'TypeScript'.",
"Scoped package detected, looking in 'be__bop/e/z'",
"File '/node_modules/@types/be__bop/e/z.d.ts' exist - use it as a name resolution result.",
"Resolving real path for '/node_modules/@types/be__bop/e/z.d.ts', result '/node_modules/@types/be__bop/e/z.d.ts'.",
"======== Module name '@be/bop/e/z' was successfully resolved to '/node_modules/@types/be__bop/e/z.d.ts'. ========"
]

View File

@@ -0,0 +1,22 @@
=== /a.ts ===
import { x } from "@cow/boy";
>x : number
import { y } from "@be/bop";
>y : number
import { z } from "@be/bop/e/z";
>z : number
=== /node_modules/@cow/boy/index.d.ts ===
export const x: number;
>x : number
=== /node_modules/@types/be__bop/index.d.ts ===
export const y: number;
>y : number
=== /node_modules/@types/be__bop/e/z.d.ts ===
export const z: number;
>z : number

View File

@@ -0,0 +1,12 @@
//// [tests/cases/conformance/moduleResolution/scopedPackagesClassic.ts] ////
//// [index.d.ts]
export const x = 0;
//// [a.ts]
import { x } from "@see/saw";
//// [a.js]
"use strict";
exports.__esModule = true;

View File

@@ -0,0 +1,8 @@
=== /a.ts ===
import { x } from "@see/saw";
>x : Symbol(x, Decl(a.ts, 0, 8))
=== /node_modules/@types/see__saw/index.d.ts ===
export const x = 0;
>x : Symbol(x, Decl(index.d.ts, 0, 12))

View File

@@ -0,0 +1,9 @@
[
"======== Resolving module '@see/saw' from '/a.ts'. ========",
"Explicitly specified module resolution kind: 'Classic'.",
"Scoped package detected, looking in 'see__saw'",
"File '/node_modules/@types/see__saw.d.ts' does not exist.",
"File '/node_modules/@types/see__saw/package.json' does not exist.",
"File '/node_modules/@types/see__saw/index.d.ts' exist - use it as a name resolution result.",
"======== Module name '@see/saw' was successfully resolved to '/node_modules/@types/see__saw/index.d.ts'. ========"
]

View File

@@ -0,0 +1,9 @@
=== /a.ts ===
import { x } from "@see/saw";
>x : 0
=== /node_modules/@types/see__saw/index.d.ts ===
export const x = 0;
>x : 0
>0 : 0

View File

@@ -0,0 +1,17 @@
// @noImplicitReferences: true
// @traceResolution: true
// @typeRoots: types
// @filename: /node_modules/@cow/boy/index.d.ts
export const x: number;
// @filename: /node_modules/@types/be__bop/index.d.ts
export const y: number;
// @filename: /node_modules/@types/be__bop/e/z.d.ts
export const z: number;
// @filename: /a.ts
import { x } from "@cow/boy";
import { y } from "@be/bop";
import { z } from "@be/bop/e/z";

View File

@@ -0,0 +1,10 @@
// @noImplicitReferences: true
// @traceResolution: true
// @typeRoots: types
// @moduleResolution: classic
// @filename: /node_modules/@types/see__saw/index.d.ts
export const x = 0;
// @filename: /a.ts
import { x } from "@see/saw";

View File

@@ -0,0 +1,9 @@
// @noImplicitReferences: true
// @traceResolution: true
// @typeRoots: types
// @filename: /node_modules/@types/beep__boop/index.d.ts
export const y = 0;
// @filename: /a.ts
/// <reference types="@beep/boop" />