mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 21:36:50 -05:00
Merge pull request #15051 from Microsoft/at_types
Support @types module resolution from scoped packages
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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" />
|
||||
@@ -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))
|
||||
|
||||
@@ -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. ========"
|
||||
]
|
||||
@@ -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
|
||||
|
||||
20
tests/baselines/reference/scopedPackages.js
Normal file
20
tests/baselines/reference/scopedPackages.js
Normal 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;
|
||||
22
tests/baselines/reference/scopedPackages.symbols
Normal file
22
tests/baselines/reference/scopedPackages.symbols
Normal 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))
|
||||
|
||||
30
tests/baselines/reference/scopedPackages.trace.json
Normal file
30
tests/baselines/reference/scopedPackages.trace.json
Normal 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'. ========"
|
||||
]
|
||||
22
tests/baselines/reference/scopedPackages.types
Normal file
22
tests/baselines/reference/scopedPackages.types
Normal 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
|
||||
|
||||
12
tests/baselines/reference/scopedPackagesClassic.js
Normal file
12
tests/baselines/reference/scopedPackagesClassic.js
Normal 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;
|
||||
8
tests/baselines/reference/scopedPackagesClassic.symbols
Normal file
8
tests/baselines/reference/scopedPackagesClassic.symbols
Normal 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))
|
||||
|
||||
@@ -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'. ========"
|
||||
]
|
||||
9
tests/baselines/reference/scopedPackagesClassic.types
Normal file
9
tests/baselines/reference/scopedPackagesClassic.types
Normal 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
|
||||
|
||||
17
tests/cases/conformance/moduleResolution/scopedPackages.ts
Normal file
17
tests/cases/conformance/moduleResolution/scopedPackages.ts
Normal 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";
|
||||
@@ -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";
|
||||
@@ -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" />
|
||||
Reference in New Issue
Block a user