Skip to content

Commit edc1a1f

Browse files
committed
Add validation and diagnostics for import attribute mismatches
Implements error reporting when import attributes don't match between import statements and ambient module declarations. Changes: - Added diagnostic messages TS18062 and TS18063 for attribute mismatches - Updated resolveExternalModule to report TS18063 when pattern matches but attributes don't match - Created comprehensive test cases for diagnostic error messages The diagnostic TS18063 is reported when: - Pattern matches but attribute values are different - Pattern matches but import has no attributes when declaration requires them - Pattern matches but import has attributes when declaration doesn't - Pattern matches but attributes have different keys or values
1 parent e4f9c7c commit edc1a1f

8 files changed

+271
-2
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4875,7 +4875,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
48754875
return false;
48764876
});
48774877
if (!hasMatchingDeclaration) {
4878-
// Pattern matched but attributes don't match - continue searching
4878+
// Pattern matched but attributes don't match
4879+
if (errorNode && moduleNotFoundError) {
4880+
error(errorNode, Diagnostics.No_ambient_module_declaration_matches_import_of_0_with_the_specified_import_attributes, moduleReference);
4881+
}
48794882
return undefined;
48804883
}
48814884
}

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8547,5 +8547,13 @@
85478547
"'{0}' is not a valid meta-property for keyword 'import'. Did you mean 'meta' or 'defer'?": {
85488548
"category": "Error",
85498549
"code": 18061
8550+
},
8551+
"Module '{0}' was resolved to '{1}', but import attributes do not match the ambient module declaration.": {
8552+
"category": "Error",
8553+
"code": 18062
8554+
},
8555+
"No ambient module declaration matches import of '{0}' with the specified import attributes.": {
8556+
"category": "Error",
8557+
"code": 18063
85508558
}
85518559
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
test.ts(2,21): error TS18063: No ambient module declaration matches import of 'styles.css' with the specified import attributes.
2+
test.ts(5,21): error TS18063: No ambient module declaration matches import of 'styles2.css' with the specified import attributes.
3+
test.ts(8,18): error TS18063: No ambient module declaration matches import of 'file.txt' with the specified import attributes.
4+
test.ts(11,18): error TS18063: No ambient module declaration matches import of 'data.json' with the specified import attributes.
5+
6+
7+
==== types.d.ts (0 errors) ====
8+
// Declare ambient modules with import attributes
9+
declare module "*.css" with { type: "css" } {
10+
const stylesheet: CSSStyleSheet;
11+
export default stylesheet;
12+
}
13+
14+
declare module "*.json" with { type: "json" } {
15+
const data: any;
16+
export default data;
17+
}
18+
19+
declare module "*.txt" {
20+
const content: string;
21+
export default content;
22+
}
23+
24+
==== test.ts (4 errors) ====
25+
// Should error - pattern matches but attributes don't match
26+
import styles1 from "styles.css" with { type: "style" };
27+
~~~~~~~~~~~~
28+
!!! error TS18063: No ambient module declaration matches import of 'styles.css' with the specified import attributes.
29+
30+
// Should error - pattern matches but import has no attributes when declaration requires them
31+
import styles2 from "styles2.css";
32+
~~~~~~~~~~~~~
33+
!!! error TS18063: No ambient module declaration matches import of 'styles2.css' with the specified import attributes.
34+
35+
// Should error - pattern matches but import has attributes when declaration doesn't
36+
import text from "file.txt" with { type: "text" };
37+
~~~~~~~~~~
38+
!!! error TS18063: No ambient module declaration matches import of 'file.txt' with the specified import attributes.
39+
40+
// Should error - pattern matches but attribute value is wrong
41+
import data from "data.json" with { type: "data" };
42+
~~~~~~~~~~~
43+
!!! error TS18063: No ambient module declaration matches import of 'data.json' with the specified import attributes.
44+
45+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//// [tests/cases/conformance/ambient/ambientModuleWithImportAttributesDiagnostics.ts] ////
2+
3+
//// [types.d.ts]
4+
// Declare ambient modules with import attributes
5+
declare module "*.css" with { type: "css" } {
6+
const stylesheet: CSSStyleSheet;
7+
export default stylesheet;
8+
}
9+
10+
declare module "*.json" with { type: "json" } {
11+
const data: any;
12+
export default data;
13+
}
14+
15+
declare module "*.txt" {
16+
const content: string;
17+
export default content;
18+
}
19+
20+
//// [test.ts]
21+
// Should error - pattern matches but attributes don't match
22+
import styles1 from "styles.css" with { type: "style" };
23+
24+
// Should error - pattern matches but import has no attributes when declaration requires them
25+
import styles2 from "styles2.css";
26+
27+
// Should error - pattern matches but import has attributes when declaration doesn't
28+
import text from "file.txt" with { type: "text" };
29+
30+
// Should error - pattern matches but attribute value is wrong
31+
import data from "data.json" with { type: "data" };
32+
33+
34+
35+
//// [test.js]
36+
export {};
37+
38+
39+
//// [test.d.ts]
40+
export {};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//// [tests/cases/conformance/ambient/ambientModuleWithImportAttributesDiagnostics.ts] ////
2+
3+
=== types.d.ts ===
4+
// Declare ambient modules with import attributes
5+
declare module "*.css" with { type: "css" } {
6+
>"*.css" : Symbol("*.css", Decl(types.d.ts, 0, 0))
7+
8+
const stylesheet: CSSStyleSheet;
9+
>stylesheet : Symbol(stylesheet, Decl(types.d.ts, 2, 9))
10+
>CSSStyleSheet : Symbol(CSSStyleSheet, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
11+
12+
export default stylesheet;
13+
>stylesheet : Symbol(stylesheet, Decl(types.d.ts, 2, 9))
14+
}
15+
16+
declare module "*.json" with { type: "json" } {
17+
>"*.json" : Symbol("*.json", Decl(types.d.ts, 4, 1))
18+
19+
const data: any;
20+
>data : Symbol(data, Decl(types.d.ts, 7, 9))
21+
22+
export default data;
23+
>data : Symbol(data, Decl(types.d.ts, 7, 9))
24+
}
25+
26+
declare module "*.txt" {
27+
>"*.txt" : Symbol("*.txt", Decl(types.d.ts, 9, 1))
28+
29+
const content: string;
30+
>content : Symbol(content, Decl(types.d.ts, 12, 9))
31+
32+
export default content;
33+
>content : Symbol(content, Decl(types.d.ts, 12, 9))
34+
}
35+
36+
=== test.ts ===
37+
// Should error - pattern matches but attributes don't match
38+
import styles1 from "styles.css" with { type: "style" };
39+
>styles1 : Symbol(styles1, Decl(test.ts, 1, 6))
40+
41+
// Should error - pattern matches but import has no attributes when declaration requires them
42+
import styles2 from "styles2.css";
43+
>styles2 : Symbol(styles2, Decl(test.ts, 4, 6))
44+
45+
// Should error - pattern matches but import has attributes when declaration doesn't
46+
import text from "file.txt" with { type: "text" };
47+
>text : Symbol(text, Decl(test.ts, 7, 6))
48+
49+
// Should error - pattern matches but attribute value is wrong
50+
import data from "data.json" with { type: "data" };
51+
>data : Symbol(data, Decl(test.ts, 10, 6))
52+
53+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//// [tests/cases/conformance/ambient/ambientModuleWithImportAttributesDiagnostics.ts] ////
2+
3+
=== types.d.ts ===
4+
// Declare ambient modules with import attributes
5+
declare module "*.css" with { type: "css" } {
6+
>"*.css" : typeof import("*.css")
7+
> : ^^^^^^^^^^^^^^^^^^^^^^
8+
9+
const stylesheet: CSSStyleSheet;
10+
>stylesheet : CSSStyleSheet
11+
> : ^^^^^^^^^^^^^
12+
13+
export default stylesheet;
14+
>stylesheet : CSSStyleSheet
15+
> : ^^^^^^^^^^^^^
16+
}
17+
18+
declare module "*.json" with { type: "json" } {
19+
>"*.json" : typeof import("*.json")
20+
> : ^^^^^^^^^^^^^^^^^^^^^^^
21+
22+
const data: any;
23+
>data : any
24+
> : ^^^
25+
26+
export default data;
27+
>data : any
28+
> : ^^^
29+
}
30+
31+
declare module "*.txt" {
32+
>"*.txt" : typeof import("*.txt")
33+
> : ^^^^^^^^^^^^^^^^^^^^^^
34+
35+
const content: string;
36+
>content : string
37+
> : ^^^^^^
38+
39+
export default content;
40+
>content : string
41+
> : ^^^^^^
42+
}
43+
44+
=== test.ts ===
45+
// Should error - pattern matches but attributes don't match
46+
import styles1 from "styles.css" with { type: "style" };
47+
>styles1 : any
48+
> : ^^^
49+
>type : any
50+
> : ^^^
51+
52+
// Should error - pattern matches but import has no attributes when declaration requires them
53+
import styles2 from "styles2.css";
54+
>styles2 : any
55+
> : ^^^
56+
57+
// Should error - pattern matches but import has attributes when declaration doesn't
58+
import text from "file.txt" with { type: "text" };
59+
>text : any
60+
> : ^^^
61+
>type : any
62+
> : ^^^
63+
64+
// Should error - pattern matches but attribute value is wrong
65+
import data from "data.json" with { type: "data" };
66+
>data : any
67+
> : ^^^
68+
>type : any
69+
> : ^^^
70+
71+

tests/baselines/reference/ambientModuleWithImportAttributesSemantics.errors.txt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
test.ts(2,33): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
22
test.ts(6,30): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
33
test.ts(14,38): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
4+
test.ts(18,19): error TS18063: No ambient module declaration matches import of 'file2.txt' with the specified import attributes.
45
test.ts(18,31): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
6+
test.ts(22,21): error TS18063: No ambient module declaration matches import of 'styles2.css' with the specified import attributes.
7+
test.ts(26,21): error TS18063: No ambient module declaration matches import of 'styles3.css' with the specified import attributes.
58
test.ts(26,35): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
9+
test.ts(30,25): error TS18063: No ambient module declaration matches import of 'module2.wasm' with the specified import attributes.
610
test.ts(30,40): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
11+
test.ts(34,25): error TS18063: No ambient module declaration matches import of 'module3.wasm' with the specified import attributes.
712
test.ts(34,40): error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
813

914

@@ -32,7 +37,7 @@ test.ts(34,40): error TS2856: Import attributes are not allowed on statements th
3237
export default module;
3338
}
3439

35-
==== test.ts (7 errors) ====
40+
==== test.ts (12 errors) ====
3641
// Should resolve correctly - matching attributes
3742
import styles from "styles.css" with { type: "css" };
3843
~~~~~~~~~~~~~~~~~~~~
@@ -57,28 +62,38 @@ test.ts(34,40): error TS2856: Import attributes are not allowed on statements th
5762

5863
// Should NOT resolve - import has attributes but declaration doesn't
5964
import text2 from "file2.txt" with { type: "text" };
65+
~~~~~~~~~~~
66+
!!! error TS18063: No ambient module declaration matches import of 'file2.txt' with the specified import attributes.
6067
~~~~~~~~~~~~~~~~~~~~~
6168
!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
6269
text2; // Should be any (no match)
6370

6471
// Should NOT resolve - import has no attributes but declaration does
6572
import styles2 from "styles2.css";
73+
~~~~~~~~~~~~~
74+
!!! error TS18063: No ambient module declaration matches import of 'styles2.css' with the specified import attributes.
6675
styles2; // Should be any (no match)
6776

6877
// Should NOT resolve - mismatched attribute values
6978
import styles3 from "styles3.css" with { type: "style" };
79+
~~~~~~~~~~~~~
80+
!!! error TS18063: No ambient module declaration matches import of 'styles3.css' with the specified import attributes.
7081
~~~~~~~~~~~~~~~~~~~~~~
7182
!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
7283
styles3; // Should be any (no match)
7384

7485
// Should NOT resolve - missing attribute
7586
import wasmModule2 from "module2.wasm" with { type: "module" };
87+
~~~~~~~~~~~~~~
88+
!!! error TS18063: No ambient module declaration matches import of 'module2.wasm' with the specified import attributes.
7689
~~~~~~~~~~~~~~~~~~~~~~~
7790
!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
7891
wasmModule2; // Should be any (no match - missing version attribute)
7992

8093
// Should NOT resolve - extra attribute
8194
import wasmModule3 from "module3.wasm" with { type: "module", version: "1", extra: "value" };
95+
~~~~~~~~~~~~~~
96+
!!! error TS18063: No ambient module declaration matches import of 'module3.wasm' with the specified import attributes.
8297
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8398
!!! error TS2856: Import attributes are not allowed on statements that compile to CommonJS 'require' calls.
8499
wasmModule3; // Should be any (no match - extra attribute)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// @declaration: true
2+
// @target: es2015
3+
// @module: esnext
4+
5+
// @filename: types.d.ts
6+
// Declare ambient modules with import attributes
7+
declare module "*.css" with { type: "css" } {
8+
const stylesheet: CSSStyleSheet;
9+
export default stylesheet;
10+
}
11+
12+
declare module "*.json" with { type: "json" } {
13+
const data: any;
14+
export default data;
15+
}
16+
17+
declare module "*.txt" {
18+
const content: string;
19+
export default content;
20+
}
21+
22+
// @filename: test.ts
23+
// Should error - pattern matches but attributes don't match
24+
import styles1 from "styles.css" with { type: "style" };
25+
26+
// Should error - pattern matches but import has no attributes when declaration requires them
27+
import styles2 from "styles2.css";
28+
29+
// Should error - pattern matches but import has attributes when declaration doesn't
30+
import text from "file.txt" with { type: "text" };
31+
32+
// Should error - pattern matches but attribute value is wrong
33+
import data from "data.json" with { type: "data" };
34+

0 commit comments

Comments
 (0)