From e84976d481a220aaf380eca9f94059eb9173ca06 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 12 Dec 2024 09:01:31 -0800 Subject: [PATCH] Do not require import attribute on type-only JSON import --- src/compiler/checker.ts | 2 +- .../nodeModulesJson(module=node16).errors.txt | 15 ++++++++++----- .../nodeModulesJson(module=node16).symbols | 14 ++++++++++---- .../nodeModulesJson(module=node16).types | 10 ++++++++++ .../nodeModulesJson(module=nodenext).errors.txt | 11 ++++++++--- .../nodeModulesJson(module=nodenext).symbols | 14 ++++++++++---- .../nodeModulesJson(module=nodenext).types | 10 ++++++++++ tests/cases/conformance/node/nodeModulesJson.ts | 2 ++ 8 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 690b17c376445..565420738d8ce 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -48122,7 +48122,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - if (moduleKind === ModuleKind.NodeNext && isOnlyImportableAsDefault(node.moduleSpecifier, resolvedModule) && !hasTypeJsonImportAttribute(node)) { + if (!importClause.isTypeOnly && moduleKind === ModuleKind.NodeNext && isOnlyImportableAsDefault(node.moduleSpecifier, resolvedModule) && !hasTypeJsonImportAttribute(node)) { // Import attributes/assertions are not allowed in --module node16, so don't suggest adding one error(node.moduleSpecifier, Diagnostics.Importing_a_JSON_file_into_an_ECMAScript_module_requires_a_type_Colon_json_import_attribute_when_module_is_set_to_0, ModuleKind[moduleKind]); } diff --git a/tests/baselines/reference/nodeModulesJson(module=node16).errors.txt b/tests/baselines/reference/nodeModulesJson(module=node16).errors.txt index 989bb7dcf9a58..ec8512329307c 100644 --- a/tests/baselines/reference/nodeModulesJson(module=node16).errors.txt +++ b/tests/baselines/reference/nodeModulesJson(module=node16).errors.txt @@ -2,10 +2,11 @@ /loosey.cts(6,9): error TS2339: Property 'default' does not exist on type '{ version: number; }'. /main.mts(5,36): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. /main.mts(6,52): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. -/main.mts(8,10): error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node16'. -/main.mts(8,41): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. -/main.mts(9,42): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. -/main.mts(10,9): error TS2339: Property 'version' does not exist on type '{ default: { version: number; }; }'. +/main.mts(9,47): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. +/main.mts(10,10): error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node16'. +/main.mts(10,41): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. +/main.mts(11,42): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. +/main.mts(12,9): error TS2339: Property 'version' does not exist on type '{ default: { version: number; }; }'. ==== /node_modules/not.json/package.json (0 errors) ==== @@ -42,7 +43,7 @@ "version": 1 } -==== /main.mts (6 errors) ==== +==== /main.mts (7 errors) ==== import { oops } from "not.json"; // Ok import moreOops from "actually-json"; // Error in nodenext import typed from "actually-json/typed"; // Error in nodenext @@ -54,6 +55,10 @@ ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. import config2 from "./config.json"; // Error in nodenext, no attribute + import type config2Type from "./config.json"; // Ok, type-only + import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'. import { version } from "./config.json" with { type: "json" }; // Error, named import ~~~~~~~ !!! error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'Node16'. diff --git a/tests/baselines/reference/nodeModulesJson(module=node16).symbols b/tests/baselines/reference/nodeModulesJson(module=node16).symbols index 42c68c640a2e7..52d983d5b9516 100644 --- a/tests/baselines/reference/nodeModulesJson(module=node16).symbols +++ b/tests/baselines/reference/nodeModulesJson(module=node16).symbols @@ -42,18 +42,24 @@ import { default as config1 } from "./config.json" with { type: "json" }; // Ok import config2 from "./config.json"; // Error in nodenext, no attribute >config2 : Symbol(config2, Decl(main.mts, 6, 6)) +import type config2Type from "./config.json"; // Ok, type-only +>config2Type : Symbol(config2Type, Decl(main.mts, 7, 6)) + +import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports +>config2Type2 : Symbol(config2Type2, Decl(main.mts, 8, 6)) + import { version } from "./config.json" with { type: "json" }; // Error, named import ->version : Symbol(version, Decl(main.mts, 7, 8)) +>version : Symbol(version, Decl(main.mts, 9, 8)) import * as config3 from "./config.json" with { type: "json" }; ->config3 : Symbol(config3, Decl(main.mts, 8, 6)) +>config3 : Symbol(config3, Decl(main.mts, 10, 6)) config3.version; // Error ->config3 : Symbol(config3, Decl(main.mts, 8, 6)) +>config3 : Symbol(config3, Decl(main.mts, 10, 6)) config3.default; // Ok >config3.default : Symbol("/config") ->config3 : Symbol(config3, Decl(main.mts, 8, 6)) +>config3 : Symbol(config3, Decl(main.mts, 10, 6)) >default : Symbol("/config") === /loosey.cts === diff --git a/tests/baselines/reference/nodeModulesJson(module=node16).types b/tests/baselines/reference/nodeModulesJson(module=node16).types index 2c41926af320a..37ac9a196dd4e 100644 --- a/tests/baselines/reference/nodeModulesJson(module=node16).types +++ b/tests/baselines/reference/nodeModulesJson(module=node16).types @@ -64,6 +64,16 @@ import config2 from "./config.json"; // Error in nodenext, no attribute >config2 : { version: number; } > : ^^^^^^^^^^^^^^^^^^^^ +import type config2Type from "./config.json"; // Ok, type-only +>config2Type : any +> : ^^^ + +import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports +>config2Type2 : any +> : ^^^ +>type : any +> : ^^^ + import { version } from "./config.json" with { type: "json" }; // Error, named import >version : number > : ^^^^^^ diff --git a/tests/baselines/reference/nodeModulesJson(module=nodenext).errors.txt b/tests/baselines/reference/nodeModulesJson(module=nodenext).errors.txt index bf355357b0905..04e6a649d3f25 100644 --- a/tests/baselines/reference/nodeModulesJson(module=nodenext).errors.txt +++ b/tests/baselines/reference/nodeModulesJson(module=nodenext).errors.txt @@ -3,8 +3,9 @@ /main.mts(2,22): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'. /main.mts(3,19): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'. /main.mts(7,21): error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'. -/main.mts(8,10): error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'NodeNext'. -/main.mts(10,9): error TS2339: Property 'version' does not exist on type '{ default: { version: number; }; }'. +/main.mts(9,47): error TS2857: Import attributes cannot be used with type-only imports or exports. +/main.mts(10,10): error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'NodeNext'. +/main.mts(12,9): error TS2339: Property 'version' does not exist on type '{ default: { version: number; }; }'. ==== /node_modules/not.json/package.json (0 errors) ==== @@ -41,7 +42,7 @@ "version": 1 } -==== /main.mts (5 errors) ==== +==== /main.mts (6 errors) ==== import { oops } from "not.json"; // Ok import moreOops from "actually-json"; // Error in nodenext ~~~~~~~~~~~~~~~ @@ -55,6 +56,10 @@ import config2 from "./config.json"; // Error in nodenext, no attribute ~~~~~~~~~~~~~~~ !!! error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'. + import type config2Type from "./config.json"; // Ok, type-only + import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2857: Import attributes cannot be used with type-only imports or exports. import { version } from "./config.json" with { type: "json" }; // Error, named import ~~~~~~~ !!! error TS1544: Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'NodeNext'. diff --git a/tests/baselines/reference/nodeModulesJson(module=nodenext).symbols b/tests/baselines/reference/nodeModulesJson(module=nodenext).symbols index 42c68c640a2e7..52d983d5b9516 100644 --- a/tests/baselines/reference/nodeModulesJson(module=nodenext).symbols +++ b/tests/baselines/reference/nodeModulesJson(module=nodenext).symbols @@ -42,18 +42,24 @@ import { default as config1 } from "./config.json" with { type: "json" }; // Ok import config2 from "./config.json"; // Error in nodenext, no attribute >config2 : Symbol(config2, Decl(main.mts, 6, 6)) +import type config2Type from "./config.json"; // Ok, type-only +>config2Type : Symbol(config2Type, Decl(main.mts, 7, 6)) + +import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports +>config2Type2 : Symbol(config2Type2, Decl(main.mts, 8, 6)) + import { version } from "./config.json" with { type: "json" }; // Error, named import ->version : Symbol(version, Decl(main.mts, 7, 8)) +>version : Symbol(version, Decl(main.mts, 9, 8)) import * as config3 from "./config.json" with { type: "json" }; ->config3 : Symbol(config3, Decl(main.mts, 8, 6)) +>config3 : Symbol(config3, Decl(main.mts, 10, 6)) config3.version; // Error ->config3 : Symbol(config3, Decl(main.mts, 8, 6)) +>config3 : Symbol(config3, Decl(main.mts, 10, 6)) config3.default; // Ok >config3.default : Symbol("/config") ->config3 : Symbol(config3, Decl(main.mts, 8, 6)) +>config3 : Symbol(config3, Decl(main.mts, 10, 6)) >default : Symbol("/config") === /loosey.cts === diff --git a/tests/baselines/reference/nodeModulesJson(module=nodenext).types b/tests/baselines/reference/nodeModulesJson(module=nodenext).types index 2c41926af320a..37ac9a196dd4e 100644 --- a/tests/baselines/reference/nodeModulesJson(module=nodenext).types +++ b/tests/baselines/reference/nodeModulesJson(module=nodenext).types @@ -64,6 +64,16 @@ import config2 from "./config.json"; // Error in nodenext, no attribute >config2 : { version: number; } > : ^^^^^^^^^^^^^^^^^^^^ +import type config2Type from "./config.json"; // Ok, type-only +>config2Type : any +> : ^^^ + +import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports +>config2Type2 : any +> : ^^^ +>type : any +> : ^^^ + import { version } from "./config.json" with { type: "json" }; // Error, named import >version : number > : ^^^^^^ diff --git a/tests/cases/conformance/node/nodeModulesJson.ts b/tests/cases/conformance/node/nodeModulesJson.ts index e231ec9b0aa1d..44469097d0d06 100644 --- a/tests/cases/conformance/node/nodeModulesJson.ts +++ b/tests/cases/conformance/node/nodeModulesJson.ts @@ -44,6 +44,8 @@ import typed from "actually-json/typed"; // Error in nodenext import config from "./config.json" with { type: "json" }; // Ok import { default as config1 } from "./config.json" with { type: "json" }; // Ok import config2 from "./config.json"; // Error in nodenext, no attribute +import type config2Type from "./config.json"; // Ok, type-only +import type config2Type2 from "./config.json" with { type: "json" }; // Error, import attributes not allowed on type-only imports import { version } from "./config.json" with { type: "json" }; // Error, named import import * as config3 from "./config.json" with { type: "json" }; config3.version; // Error