Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion internal/compiler/fileloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ func (p *fileLoader) resolveAutomaticTypeDirectives(containingFileName string) (
toParse = make([]resolvedRef, 0, len(automaticTypeDirectiveNames))
typeResolutionsInFile = make(module.ModeAwareCache[*module.ResolvedTypeReferenceDirective], len(automaticTypeDirectiveNames))
for _, name := range automaticTypeDirectiveNames {
resolutionMode := core.ModuleKindNodeNext
// Under node16/nodenext module resolution, load `types`/ata include names as cjs resolution results by passing an `undefined` mode.
// Under bundler module resolution, this also triggers the "import" condition to be used.
resolutionMode := core.ResolutionModeNone
resolved, trace := p.resolver.ResolveTypeReferenceDirective(name, containingFileName, resolutionMode, nil)
typeResolutionsInFile[module.ModeAwareCacheKey{Name: name, Mode: resolutionMode}] = resolved
typeResolutionsTrace = append(typeResolutionsTrace, trace...)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//// [tests/cases/compiler/automaticTypeDirectiveResolutionBundler.ts] ////

=== /index.ts ===
// The automatic type directive "pkg" from @types should resolve to esm.d.mts
// because bundler resolution uses the "import" condition.
// If the wrong file is resolved, we'll get a type error due to conflicting declarations.
import type { PkgType } from "pkg";
>PkgType : Symbol(PkgType, Decl(index.ts, 3, 13))

// This should work if esm.d.mts is correctly resolved
const x: PkgType = { esm: true };
>x : Symbol(x, Decl(index.ts, 6, 5))
>PkgType : Symbol(PkgType, Decl(index.ts, 3, 13))
>esm : Symbol(esm, Decl(index.ts, 6, 20))

=== /node_modules/pkg/esm.d.mts ===
// This file should be resolved when using bundler resolution with "import" condition
export interface PkgType {
>PkgType : Symbol(PkgType, Decl(esm.d.mts, 0, 0))

esm: true;
>esm : Symbol(PkgType.esm, Decl(esm.d.mts, 1, 26))
}
declare global {
>global : Symbol(global, Decl(esm.d.mts, 3, 1))

var expectedCondition: "import";
>expectedCondition : Symbol(expectedCondition, Decl(esm.d.mts, 5, 7))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
======== Resolving module 'pkg' from '/index.ts'. ========
Explicitly specified module resolution kind: 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
File '/package.json' does not exist.
Loading module 'pkg' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.
Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.
Found 'package.json' at '/node_modules/pkg/package.json'.
Entering conditional exports.
Matched 'exports' condition 'import'.
Entering conditional exports.
Matched 'exports' condition 'types'.
Using 'exports' subpath '.' with target './esm.d.mts'.
File '/node_modules/pkg/esm.d.mts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolved under condition 'types'.
Exiting conditional exports.
Resolved under condition 'import'.
Exiting conditional exports.
Resolving real path for '/node_modules/pkg/esm.d.mts', result '/node_modules/pkg/esm.d.mts'.
======== Module name 'pkg' was successfully resolved to '/node_modules/pkg/esm.d.mts' with Package ID 'pkg/esm.d.mts@1.0.0'. ========
======== Resolving type reference directive 'pkg', containing file '/.src/__inferred type names__.ts', root directory '/.src/node_modules/@types,/node_modules/@types'. ========
Resolving with primary search path '/.src/node_modules/@types, /node_modules/@types'.
Directory '/.src/node_modules/@types' does not exist, skipping all lookups in it.
Directory '/node_modules/@types' does not exist, skipping all lookups in it.
Looking up in 'node_modules' folder, initial location '/.src'.
Searching all ancestor node_modules directories for preferred extensions: Declaration.
Directory '/.src/node_modules' does not exist, skipping all lookups in it.
Directory '/.src/node_modules/@types' does not exist, skipping all lookups in it.
File '/node_modules/pkg/package.json' exists according to earlier cached lookups.
Entering conditional exports.
Matched 'exports' condition 'import'.
Entering conditional exports.
Matched 'exports' condition 'types'.
Using 'exports' subpath '.' with target './esm.d.mts'.
File '/node_modules/pkg/esm.d.mts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolved under condition 'types'.
Exiting conditional exports.
Resolved under condition 'import'.
Exiting conditional exports.
Resolving real path for '/node_modules/pkg/esm.d.mts', result '/node_modules/pkg/esm.d.mts'.
======== Type reference directive 'pkg' was successfully resolved to '/node_modules/pkg/esm.d.mts' with Package ID 'pkg/esm.d.mts@1.0.0', primary: false. ========
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//// [tests/cases/compiler/automaticTypeDirectiveResolutionBundler.ts] ////

=== /index.ts ===
// The automatic type directive "pkg" from @types should resolve to esm.d.mts
// because bundler resolution uses the "import" condition.
// If the wrong file is resolved, we'll get a type error due to conflicting declarations.
import type { PkgType } from "pkg";
>PkgType : PkgType

// This should work if esm.d.mts is correctly resolved
const x: PkgType = { esm: true };
>x : PkgType
>{ esm: true } : { esm: true; }
>esm : true
>true : true

=== /node_modules/pkg/esm.d.mts ===
// This file should be resolved when using bundler resolution with "import" condition
export interface PkgType {
esm: true;
>esm : true
>true : true
}
declare global {
>global : typeof global

var expectedCondition: "import";
>expectedCondition : "import"
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// @noImplicitReferences: true
// @module: esnext
// @moduleResolution: bundler
// @types: pkg
// @traceResolution: true
// @noEmit: true
// @strict: true

// @filename: /node_modules/pkg/package.json
{
"name": "pkg",
"version": "1.0.0",
"exports": {
".": {
"import": {
"types": "./esm.d.mts"
},
"default": {
"types": "./cjs.d.ts"
}
}
}
}

// @filename: /node_modules/pkg/esm.d.mts
// This file should be resolved when using bundler resolution with "import" condition
export interface PkgType {
esm: true;
}
declare global {
var expectedCondition: "import";
}

// @filename: /node_modules/pkg/cjs.d.ts
// This file should NOT be resolved - it's the "default" condition fallback
export interface PkgType {
cjs: true; // Different shape - will cause error if wrong file is used
}
declare global {
var expectedCondition: "default"; // Conflicts with esm.d.mts if both are loaded
}

// @filename: /index.ts
// The automatic type directive "pkg" from @types should resolve to esm.d.mts
// because bundler resolution uses the "import" condition.
// If the wrong file is resolved, we'll get a type error due to conflicting declarations.
import type { PkgType } from "pkg";

// This should work if esm.d.mts is correctly resolved
const x: PkgType = { esm: true };
Loading