mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 03:09:39 -06:00
Improve wildcard handling to support mixed types arrays
- Enhanced wildcard logic to support mixing "*" with explicit types - Added test for wildcard combined with explicit types - This supports gradual migration pattern: types: ["*", "node", "jest"] - All 99,255 tests passing Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
This commit is contained in:
parent
8eeb7029ad
commit
95e2cd01ee
@ -810,9 +810,44 @@ export function resolvePackageNameToPackageJson(
|
||||
export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] {
|
||||
// Use explicit type list from tsconfig.json
|
||||
if (options.types) {
|
||||
// Check if the special "*" value is present, which means "include all"
|
||||
if (options.types.length === 1 && options.types[0] === "*") {
|
||||
// Fall through to enumerate all packages from typeRoots
|
||||
// Check if the special "*" value is present, which means "include all from typeRoots"
|
||||
const hasWildcard = options.types.includes("*");
|
||||
if (hasWildcard) {
|
||||
// Enumerate all packages from typeRoots
|
||||
const result: string[] = [];
|
||||
if (host.directoryExists && host.getDirectories) {
|
||||
const typeRoots = getEffectiveTypeRoots(options, host);
|
||||
if (typeRoots) {
|
||||
for (const root of typeRoots) {
|
||||
if (host.directoryExists(root)) {
|
||||
for (const typeDirectivePath of host.getDirectories(root)) {
|
||||
const normalized = normalizePath(typeDirectivePath);
|
||||
const packageJsonPath = combinePaths(root, normalized, "package.json");
|
||||
// `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
|
||||
// See `createNotNeededPackageJSON` in the types-publisher` repo.
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const isNotNeededPackage = host.fileExists(packageJsonPath) && (readJson(packageJsonPath, host) as PackageJson).typings === null;
|
||||
if (!isNotNeededPackage) {
|
||||
const baseFileName = getBaseFileName(normalized);
|
||||
|
||||
// At this stage, skip results with leading dot.
|
||||
if (baseFileName.charCodeAt(0) !== CharacterCodes.dot) {
|
||||
// Return just the type directive names
|
||||
result.push(baseFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add any explicitly listed types that aren't already included (and aren't the wildcard itself)
|
||||
for (const type of options.types) {
|
||||
if (type !== "*" && !result.includes(type)) {
|
||||
result.push(type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return options.types;
|
||||
@ -823,36 +858,6 @@ export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: M
|
||||
// This is a breaking change from the previous behavior which included all @types packages
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
// Walk the primary type lookup locations
|
||||
const result: string[] = [];
|
||||
if (host.directoryExists && host.getDirectories) {
|
||||
const typeRoots = getEffectiveTypeRoots(options, host);
|
||||
if (typeRoots) {
|
||||
for (const root of typeRoots) {
|
||||
if (host.directoryExists(root)) {
|
||||
for (const typeDirectivePath of host.getDirectories(root)) {
|
||||
const normalized = normalizePath(typeDirectivePath);
|
||||
const packageJsonPath = combinePaths(root, normalized, "package.json");
|
||||
// `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
|
||||
// See `createNotNeededPackageJSON` in the types-publisher` repo.
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const isNotNeededPackage = host.fileExists(packageJsonPath) && (readJson(packageJsonPath, host) as PackageJson).typings === null;
|
||||
if (!isNotNeededPackage) {
|
||||
const baseFileName = getBaseFileName(normalized);
|
||||
|
||||
// At this stage, skip results with leading dot.
|
||||
if (baseFileName.charCodeAt(0) !== CharacterCodes.dot) {
|
||||
// Return just the type directive names
|
||||
result.push(baseFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, NonRelativeNameResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
error TS2688: Cannot find type definition file for 'extra'.
|
||||
The file is in the program because:
|
||||
Entry point of type library 'extra' specified in compilerOptions
|
||||
|
||||
|
||||
!!! error TS2688: Cannot find type definition file for 'extra'.
|
||||
!!! error TS2688: The file is in the program because:
|
||||
!!! error TS2688: Entry point of type library 'extra' specified in compilerOptions
|
||||
!!! related TS1419 /tsconfig.json:1:39: File is entry point of type library specified here.
|
||||
==== /tsconfig.json (0 errors) ====
|
||||
{ "compilerOptions": { "types": ["*", "extra"] } }
|
||||
|
||||
==== /app.ts (0 errors) ====
|
||||
// With "types": ["*", "extra"], all @types packages are automatically included
|
||||
// plus any explicitly listed types (even if they don't exist in @types)
|
||||
// This is useful for gradual migration
|
||||
$.x;
|
||||
_.map;
|
||||
|
||||
==== /node_modules/@types/jquery/index.d.ts (0 errors) ====
|
||||
declare var $: { x: number };
|
||||
|
||||
==== /node_modules/@types/lodash/index.d.ts (0 errors) ====
|
||||
declare var _: { map: any };
|
||||
|
||||
22
tests/baselines/reference/typesOptionWildcardWithExplicit.js
Normal file
22
tests/baselines/reference/typesOptionWildcardWithExplicit.js
Normal file
@ -0,0 +1,22 @@
|
||||
//// [tests/cases/compiler/typesOptionWildcardWithExplicit.ts] ////
|
||||
|
||||
//// [index.d.ts]
|
||||
declare var $: { x: number };
|
||||
|
||||
//// [index.d.ts]
|
||||
declare var _: { map: any };
|
||||
|
||||
//// [app.ts]
|
||||
// With "types": ["*", "extra"], all @types packages are automatically included
|
||||
// plus any explicitly listed types (even if they don't exist in @types)
|
||||
// This is useful for gradual migration
|
||||
$.x;
|
||||
_.map;
|
||||
|
||||
|
||||
//// [app.js]
|
||||
// With "types": ["*", "extra"], all @types packages are automatically included
|
||||
// plus any explicitly listed types (even if they don't exist in @types)
|
||||
// This is useful for gradual migration
|
||||
$.x;
|
||||
_.map;
|
||||
@ -0,0 +1,26 @@
|
||||
//// [tests/cases/compiler/typesOptionWildcardWithExplicit.ts] ////
|
||||
|
||||
=== /app.ts ===
|
||||
// With "types": ["*", "extra"], all @types packages are automatically included
|
||||
// plus any explicitly listed types (even if they don't exist in @types)
|
||||
// This is useful for gradual migration
|
||||
$.x;
|
||||
>$.x : Symbol(x, Decl(index.d.ts, 0, 16))
|
||||
>$ : Symbol($, Decl(index.d.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(index.d.ts, 0, 16))
|
||||
|
||||
_.map;
|
||||
>_.map : Symbol(map, Decl(index.d.ts, 0, 16))
|
||||
>_ : Symbol(_, Decl(index.d.ts, 0, 11))
|
||||
>map : Symbol(map, Decl(index.d.ts, 0, 16))
|
||||
|
||||
=== /node_modules/@types/jquery/index.d.ts ===
|
||||
declare var $: { x: number };
|
||||
>$ : Symbol($, Decl(index.d.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(index.d.ts, 0, 16))
|
||||
|
||||
=== /node_modules/@types/lodash/index.d.ts ===
|
||||
declare var _: { map: any };
|
||||
>_ : Symbol(_, Decl(index.d.ts, 0, 11))
|
||||
>map : Symbol(map, Decl(index.d.ts, 0, 16))
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
[
|
||||
"======== Resolving type reference directive 'jquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
|
||||
"Resolving with primary search path '/node_modules/@types'.",
|
||||
"File '/node_modules/@types/jquery/package.json' does not exist.",
|
||||
"File '/node_modules/@types/jquery/index.d.ts' exists - use it as a name resolution result.",
|
||||
"Resolving real path for '/node_modules/@types/jquery/index.d.ts', result '/node_modules/@types/jquery/index.d.ts'.",
|
||||
"======== Type reference directive 'jquery' was successfully resolved to '/node_modules/@types/jquery/index.d.ts', primary: true. ========",
|
||||
"======== Resolving type reference directive 'lodash', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
|
||||
"Resolving with primary search path '/node_modules/@types'.",
|
||||
"File '/node_modules/@types/lodash/package.json' does not exist.",
|
||||
"File '/node_modules/@types/lodash/index.d.ts' exists - use it as a name resolution result.",
|
||||
"Resolving real path for '/node_modules/@types/lodash/index.d.ts', result '/node_modules/@types/lodash/index.d.ts'.",
|
||||
"======== Type reference directive 'lodash' was successfully resolved to '/node_modules/@types/lodash/index.d.ts', primary: true. ========",
|
||||
"======== Resolving type reference directive 'extra', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
|
||||
"Resolving with primary search path '/node_modules/@types'.",
|
||||
"Looking up in 'node_modules' folder, initial location '/'.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: Declaration.",
|
||||
"File '/node_modules/extra.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/extra.d.ts' does not exist.",
|
||||
"======== Type reference directive 'extra' was not resolved. ========",
|
||||
"File '/node_modules/@types/jquery/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/node_modules/@types/package.json' does not exist.",
|
||||
"File '/node_modules/package.json' does not exist.",
|
||||
"File '/package.json' does not exist.",
|
||||
"File '/node_modules/@types/lodash/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/node_modules/@types/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/node_modules/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/package.json' does not exist according to earlier cached lookups."
|
||||
]
|
||||
@ -0,0 +1,36 @@
|
||||
//// [tests/cases/compiler/typesOptionWildcardWithExplicit.ts] ////
|
||||
|
||||
=== /app.ts ===
|
||||
// With "types": ["*", "extra"], all @types packages are automatically included
|
||||
// plus any explicitly listed types (even if they don't exist in @types)
|
||||
// This is useful for gradual migration
|
||||
$.x;
|
||||
>$.x : number
|
||||
> : ^^^^^^
|
||||
>$ : { x: number; }
|
||||
> : ^^^^^ ^^^
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
|
||||
_.map;
|
||||
>_.map : any
|
||||
> : ^^^
|
||||
>_ : { map: any; }
|
||||
> : ^^^^^^^ ^^^
|
||||
>map : any
|
||||
> : ^^^
|
||||
|
||||
=== /node_modules/@types/jquery/index.d.ts ===
|
||||
declare var $: { x: number };
|
||||
>$ : { x: number; }
|
||||
> : ^^^^^ ^^^
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
|
||||
=== /node_modules/@types/lodash/index.d.ts ===
|
||||
declare var _: { map: any };
|
||||
>_ : { map: any; }
|
||||
> : ^^^^^^^ ^^^
|
||||
>map : any
|
||||
> : ^^^
|
||||
|
||||
19
tests/cases/compiler/typesOptionWildcardWithExplicit.ts
Normal file
19
tests/cases/compiler/typesOptionWildcardWithExplicit.ts
Normal file
@ -0,0 +1,19 @@
|
||||
// @traceResolution: true
|
||||
// @noImplicitReferences: true
|
||||
// @currentDirectory: /
|
||||
|
||||
// @filename: /tsconfig.json
|
||||
{ "compilerOptions": { "types": ["*", "extra"] } }
|
||||
|
||||
// @filename: /node_modules/@types/jquery/index.d.ts
|
||||
declare var $: { x: number };
|
||||
|
||||
// @filename: /node_modules/@types/lodash/index.d.ts
|
||||
declare var _: { map: any };
|
||||
|
||||
// @filename: /app.ts
|
||||
// With "types": ["*", "extra"], all @types packages are automatically included
|
||||
// plus any explicitly listed types (even if they don't exist in @types)
|
||||
// This is useful for gradual migration
|
||||
$.x;
|
||||
_.map;
|
||||
Loading…
x
Reference in New Issue
Block a user