diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 4464564837b8a..3a0e0b2558acd 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -3368,7 +3368,9 @@ func (c *Checker) checkTemplateLiteralType(node *ast.Node) { func (c *Checker) checkImportType(node *ast.Node) { c.checkSourceElement(node.AsImportTypeNode().Argument) if attributes := node.AsImportTypeNode().Attributes; attributes != nil { - c.getResolutionModeOverride(attributes.AsImportAttributes(), true /*reportErrors*/) + importAttributes := attributes.AsImportAttributes() + c.checkGrammarImportAttributeValues(importAttributes) + c.getResolutionModeOverride(importAttributes, true /*reportErrors*/) } c.checkTypeReferenceOrImport(node) c.checkImportAttributes(node) @@ -5492,14 +5494,9 @@ func (c *Checker) checkExternalImportOrExportDeclaration(node *ast.Node) bool { if !ast.IsImportEqualsDeclaration(node) { attributes := ast.GetImportAttributes(node) if attributes != nil { - hasError := false - for _, attr := range attributes.AsImportAttributes().Attributes.Nodes { - if !ast.IsStringLiteral(attr.AsImportAttribute().Value) { - hasError = true - c.error(attr.AsImportAttribute().Value, diagnostics.Import_attribute_values_must_be_string_literal_expressions) - } + if c.checkGrammarImportAttributeValues(attributes.AsImportAttributes()) { + return false } - return !hasError } } return true diff --git a/tsc/internal/checker/grammarchecks.go b/tsc/internal/checker/grammarchecks.go index a942d0381aac2..cc274d8b2fd4d 100644 --- a/tsc/internal/checker/grammarchecks.go +++ b/tsc/internal/checker/grammarchecks.go @@ -2120,6 +2120,19 @@ func (c *Checker) checkGrammarImportClause(node *ast.ImportClause) bool { return false } +func (c *Checker) checkGrammarImportAttributeValues(node *ast.ImportAttributes) bool { + hasError := false + for _, attribute := range node.Attributes.Nodes { + value := attribute.AsImportAttribute().Value + if ast.IsStringLiteral(value) { + continue + } + hasError = true + c.error(value, diagnostics.Import_attribute_values_must_be_string_literal_expressions) + } + return hasError +} + func (c *Checker) checkGrammarTypeOnlyNamedImportsOrExports(namedBindings *ast.Node) bool { nodeList := namedBindings.ElementList() for _, specifier := range nodeList.Nodes { diff --git a/tsc/testdata/baselines/reference/conformance/importAttributes12.errors.txt b/tsc/testdata/baselines/reference/conformance/importAttributes12.errors.txt new file mode 100644 index 0000000000000..0e1c8f0e4524a --- /dev/null +++ b/tsc/testdata/baselines/reference/conformance/importAttributes12.errors.txt @@ -0,0 +1,55 @@ +importAttributes12.ts(10,12): error TS2858: Import attribute values must be string literal expressions. +importAttributes12.ts(16,28): error TS2858: Import attribute values must be string literal expressions. +importAttributes12.ts(21,11): error TS2322: Type '{ "resolution-mode": 0; }' is not assignable to type 'ImportAttributes'. + Property 'resolution-mode' is incompatible with index signature. + Type 'number' is not assignable to type 'string'. +importAttributes12.ts(22,28): error TS2858: Import attribute values must be string literal expressions. +importAttributes12.ts(28,28): error TS2858: Import attribute values must be string literal expressions. + + +==== importAttributes12.ts (5 errors) ==== + declare module "dependency" { + export interface Type {} + } + + type T1 = typeof import("dependency", { with: { "resolution-mode": "import" } }); + type T2 = import("dependency", { with: { "resolution-mode": "require" } }).Type; + + type T3 = typeof import("dependency", { + with: { + a: (() => "value")(), + ~~~~~~~~~~~~~~~~~ +!!! error TS2858: Import attribute values must be string literal expressions. + }, + }); + + type T4 = import("dependency", { + with: { + "resolution-mode": (() => "import")(), + ~~~~~~~~~~~~~~~~~~ +!!! error TS2858: Import attribute values must be string literal expressions. + }, + }).Type; + + type T5 = import("dependency", { + with: { + ~ + "resolution-mode": 0, + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ +!!! error TS2858: Import attribute values must be string literal expressions. + }, + ~~~~~ +!!! error TS2322: Type '{ "resolution-mode": 0; }' is not assignable to type 'ImportAttributes'. +!!! error TS2322: Property 'resolution-mode' is incompatible with index signature. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + }).Type; + + type T6 = import("dependency", { + with: { + "resolution-mode": `import`, + ~~~~~~~~ +!!! error TS2858: Import attribute values must be string literal expressions. + }, + }).Type; + \ No newline at end of file diff --git a/tsc/testdata/tests/cases/conformance/importAttributes/importAttributes12.ts b/tsc/testdata/tests/cases/conformance/importAttributes/importAttributes12.ts new file mode 100644 index 0000000000000..b4d8e6a29f34f --- /dev/null +++ b/tsc/testdata/tests/cases/conformance/importAttributes/importAttributes12.ts @@ -0,0 +1,35 @@ +// @target: esnext +// @module: esnext +// @noEmit: true +// @noTypesAndSymbols: true + +declare module "dependency" { + export interface Type {} +} + +type T1 = typeof import("dependency", { with: { "resolution-mode": "import" } }); +type T2 = import("dependency", { with: { "resolution-mode": "require" } }).Type; + +type T3 = typeof import("dependency", { + with: { + a: (() => "value")(), + }, +}); + +type T4 = import("dependency", { + with: { + "resolution-mode": (() => "import")(), + }, +}).Type; + +type T5 = import("dependency", { + with: { + "resolution-mode": 0, + }, +}).Type; + +type T6 = import("dependency", { + with: { + "resolution-mode": `import`, + }, +}).Type;