diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 10ddb3c0c88b4..73250c46b97e4 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -15695,9 +15695,11 @@ func (c *Checker) resolveExternalModule( } return c.tryResolvePatternAmbientModule(c.getMergedSymbol(sourceFile.Symbol), moduleReference, importAttributesType) } - patternAmbientModule := c.tryResolvePatternAmbientModule(nil /*resolvedSymbol*/, moduleReference, importAttributesType) - if patternAmbientModule != nil { - return patternAmbientModule + if !c.isEmptyObjectType(importAttributesType) { + patternAmbientModule := c.tryResolvePatternAmbientModule(nil /*resolvedSymbol*/, moduleReference, importAttributesType) + if patternAmbientModule != nil { + return patternAmbientModule + } } if errorNode != nil && moduleNotFoundError != nil && !isSideEffectImport(errorNode) { c.error(errorNode, diagnostics.File_0_is_not_a_module, resolvedModule.ResolvedFileName) diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedEmptyModule.errors.txt b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedEmptyModule.errors.txt new file mode 100644 index 0000000000000..f5c57582a5fbf --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedEmptyModule.errors.txt @@ -0,0 +1,61 @@ +/src/main.ts(4,8): error TS1192: Module '"/src/script"' has no default export. +/src/main.ts(5,7): error TS2322: Type 'typeof import("/stub")' is not assignable to type 'number'. +/src/main.ts(6,7): error TS2322: Type 'typeof import("/stub")' is not assignable to type 'number'. +/src/main.ts(7,7): error TS2322: Type 'typeof import("/generated/component.svelte")' is not assignable to type 'number'. + + +==== /tsconfig.json (0 errors) ==== + { + "compilerOptions": { + "paths": { "x.svelte": ["./stub.d.ts"] }, + "rootDirs": ["./src", "./generated"] + }, + "files": ["ambient.d.ts", "src/main.ts"] + } + +==== /ambient.d.ts (0 errors) ==== + declare module "*.svelte" { + const value: number; + export default value; + } + declare module "*.svelte" with { type: "text" } { + const value: string; + export default value; + } + declare module "*.js" { + const value: number; + export default value; + } + +==== /src/main.ts (4 errors) ==== + import fromPaths from "x.svelte"; + import emptyAttributes from "x.svelte" with {}; + import fromRootDirs from "./component.svelte"; + import fromRelative from "./script.js"; + ~~~~~~~~~~~~ +!!! error TS1192: Module '"/src/script"' has no default export. + const fromPathsValue: number = fromPaths; + ~~~~~~~~~~~~~~ +!!! error TS2322: Type 'typeof import("/stub")' is not assignable to type 'number'. + const emptyAttributesValue: number = emptyAttributes; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'typeof import("/stub")' is not assignable to type 'number'. + const fromRootDirsValue: number = fromRootDirs; + ~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'typeof import("/generated/component.svelte")' is not assignable to type 'number'. + + import text from "x.svelte" with { type: "text" }; + const textValue: string = text; + + import missing from "./missing.svelte"; + const missingValue: number = missing; + +==== /stub.d.ts (0 errors) ==== + export {}; + +==== /generated/component.svelte.d.ts (0 errors) ==== + export {}; + +==== /src/script.ts (0 errors) ==== + export {}; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedScript.errors.txt b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedScript.errors.txt new file mode 100644 index 0000000000000..4720210c86ed8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedScript.errors.txt @@ -0,0 +1,59 @@ +/src/main.ts(1,23): error TS2306: File '/stub.d.ts' is not a module. +/src/main.ts(2,29): error TS2306: File '/stub.d.ts' is not a module. +/src/main.ts(3,26): error TS2306: File '/generated/component.svelte.d.ts' is not a module. +/src/main.ts(4,26): error TS2306: File '/src/script.ts' is not a module. + + +==== /tsconfig.json (0 errors) ==== + { + "compilerOptions": { + "paths": { "x.svelte": ["./stub.d.ts"] }, + "rootDirs": ["./src", "./generated"] + }, + "files": ["ambient.d.ts", "src/main.ts"] + } + +==== /ambient.d.ts (0 errors) ==== + declare module "*.svelte" { + const value: number; + export default value; + } + declare module "*.svelte" with { type: "text" } { + const value: string; + export default value; + } + declare module "*.js" { + const value: number; + export default value; + } + +==== /src/main.ts (4 errors) ==== + import fromPaths from "x.svelte"; + ~~~~~~~~~~ +!!! error TS2306: File '/stub.d.ts' is not a module. + import emptyAttributes from "x.svelte" with {}; + ~~~~~~~~~~ +!!! error TS2306: File '/stub.d.ts' is not a module. + import fromRootDirs from "./component.svelte"; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2306: File '/generated/component.svelte.d.ts' is not a module. + import fromRelative from "./script.js"; + ~~~~~~~~~~~~~ +!!! error TS2306: File '/src/script.ts' is not a module. + const fromPathsValue: string = fromPaths; + + import text from "x.svelte" with { type: "text" }; + const textValue: string = text; + + import missing from "./missing.svelte"; + const missingValue: number = missing; + +==== /stub.d.ts (0 errors) ==== + // A resolved script must not fall back to a pattern ambient module without attributes. + +==== /generated/component.svelte.d.ts (0 errors) ==== + // A script resolved through rootDirs. + +==== /src/script.ts (0 errors) ==== + // A script resolved through a relative import. + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedScriptWithoutPaths.errors.txt b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedScriptWithoutPaths.errors.txt new file mode 100644 index 0000000000000..8e40142d4812e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/patternAmbientModuleResolvedScriptWithoutPaths.errors.txt @@ -0,0 +1,55 @@ +/src/main.ts(3,26): error TS2306: File '/generated/component.svelte.d.ts' is not a module. +/src/main.ts(4,26): error TS2306: File '/src/script.ts' is not a module. +/src/main.ts(5,7): error TS2322: Type 'number' is not assignable to type 'string'. + + +==== /tsconfig.json (0 errors) ==== + { + "compilerOptions": { + "rootDirs": ["./src", "./generated"] + }, + "files": ["ambient.d.ts", "src/main.ts"] + } + +==== /ambient.d.ts (0 errors) ==== + declare module "*.svelte" { + const value: number; + export default value; + } + declare module "*.svelte" with { type: "text" } { + const value: string; + export default value; + } + declare module "*.js" { + const value: number; + export default value; + } + +==== /src/main.ts (3 errors) ==== + import fromPaths from "x.svelte"; + import emptyAttributes from "x.svelte" with {}; + import fromRootDirs from "./component.svelte"; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2306: File '/generated/component.svelte.d.ts' is not a module. + import fromRelative from "./script.js"; + ~~~~~~~~~~~~~ +!!! error TS2306: File '/src/script.ts' is not a module. + const fromPathsValue: string = fromPaths; + ~~~~~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + + import text from "x.svelte" with { type: "text" }; + const textValue: string = text; + + import missing from "./missing.svelte"; + const missingValue: number = missing; + +==== /stub.d.ts (0 errors) ==== + // This file is not resolved without a paths mapping. + +==== /generated/component.svelte.d.ts (0 errors) ==== + // A script resolved through rootDirs. + +==== /src/script.ts (0 errors) ==== + // A script resolved through a relative import. + \ No newline at end of file diff --git a/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedEmptyModule.ts b/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedEmptyModule.ts new file mode 100644 index 0000000000000..b7c9cbc02c495 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedEmptyModule.ts @@ -0,0 +1,52 @@ +// @strict: true +// @module: esnext +// @moduleResolution: bundler +// @noEmit: true +// @noTypesAndSymbols: true + +// @filename: /tsconfig.json +{ + "compilerOptions": { + "paths": { "x.svelte": ["./stub.d.ts"] }, + "rootDirs": ["./src", "./generated"] + }, + "files": ["ambient.d.ts", "src/main.ts"] +} + +// @filename: /ambient.d.ts +declare module "*.svelte" { + const value: number; + export default value; +} +declare module "*.svelte" with { type: "text" } { + const value: string; + export default value; +} +declare module "*.js" { + const value: number; + export default value; +} + +// @filename: /stub.d.ts +export {}; + +// @filename: /generated/component.svelte.d.ts +export {}; + +// @filename: /src/script.ts +export {}; + +// @filename: /src/main.ts +import fromPaths from "x.svelte"; +import emptyAttributes from "x.svelte" with {}; +import fromRootDirs from "./component.svelte"; +import fromRelative from "./script.js"; +const fromPathsValue: number = fromPaths; +const emptyAttributesValue: number = emptyAttributes; +const fromRootDirsValue: number = fromRootDirs; + +import text from "x.svelte" with { type: "text" }; +const textValue: string = text; + +import missing from "./missing.svelte"; +const missingValue: number = missing; diff --git a/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedScript.ts b/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedScript.ts new file mode 100644 index 0000000000000..782e943c07625 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedScript.ts @@ -0,0 +1,50 @@ +// @strict: true +// @module: esnext +// @moduleResolution: bundler +// @noEmit: true +// @noTypesAndSymbols: true + +// @filename: /tsconfig.json +{ + "compilerOptions": { + "paths": { "x.svelte": ["./stub.d.ts"] }, + "rootDirs": ["./src", "./generated"] + }, + "files": ["ambient.d.ts", "src/main.ts"] +} + +// @filename: /ambient.d.ts +declare module "*.svelte" { + const value: number; + export default value; +} +declare module "*.svelte" with { type: "text" } { + const value: string; + export default value; +} +declare module "*.js" { + const value: number; + export default value; +} + +// @filename: /stub.d.ts +// A resolved script must not fall back to a pattern ambient module without attributes. + +// @filename: /generated/component.svelte.d.ts +// A script resolved through rootDirs. + +// @filename: /src/script.ts +// A script resolved through a relative import. + +// @filename: /src/main.ts +import fromPaths from "x.svelte"; +import emptyAttributes from "x.svelte" with {}; +import fromRootDirs from "./component.svelte"; +import fromRelative from "./script.js"; +const fromPathsValue: string = fromPaths; + +import text from "x.svelte" with { type: "text" }; +const textValue: string = text; + +import missing from "./missing.svelte"; +const missingValue: number = missing; diff --git a/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedScriptWithoutPaths.ts b/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedScriptWithoutPaths.ts new file mode 100644 index 0000000000000..232d40cd9f3e8 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/patternAmbientModuleResolvedScriptWithoutPaths.ts @@ -0,0 +1,49 @@ +// @strict: true +// @module: esnext +// @moduleResolution: bundler +// @noEmit: true +// @noTypesAndSymbols: true + +// @filename: /tsconfig.json +{ + "compilerOptions": { + "rootDirs": ["./src", "./generated"] + }, + "files": ["ambient.d.ts", "src/main.ts"] +} + +// @filename: /ambient.d.ts +declare module "*.svelte" { + const value: number; + export default value; +} +declare module "*.svelte" with { type: "text" } { + const value: string; + export default value; +} +declare module "*.js" { + const value: number; + export default value; +} + +// @filename: /stub.d.ts +// This file is not resolved without a paths mapping. + +// @filename: /generated/component.svelte.d.ts +// A script resolved through rootDirs. + +// @filename: /src/script.ts +// A script resolved through a relative import. + +// @filename: /src/main.ts +import fromPaths from "x.svelte"; +import emptyAttributes from "x.svelte" with {}; +import fromRootDirs from "./component.svelte"; +import fromRelative from "./script.js"; +const fromPathsValue: string = fromPaths; + +import text from "x.svelte" with { type: "text" }; +const textValue: string = text; + +import missing from "./missing.svelte"; +const missingValue: number = missing;