mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 11:24:49 -05:00
Do not require import attributes for JSON imports in --module node16 (#60673)
This commit is contained in:
@@ -48100,7 +48100,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
if (isOnlyImportableAsDefault(node.moduleSpecifier, resolvedModule) && !hasTypeJsonImportAttribute(node)) {
|
||||
if (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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/loosey.cts(1,36): error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'.
|
||||
/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; }; }'.
|
||||
|
||||
|
||||
==== /node_modules/not.json/package.json (0 errors) ====
|
||||
{
|
||||
"name": "not.json",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"exports": "./index.js"
|
||||
}
|
||||
|
||||
==== /node_modules/not.json/index.d.ts (0 errors) ====
|
||||
export function oops(json: string): any;
|
||||
|
||||
==== /node_modules/actually-json/package.json (0 errors) ====
|
||||
{
|
||||
"name": "actually-json",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.json",
|
||||
"./typed": "./typed.d.json.ts"
|
||||
}
|
||||
}
|
||||
|
||||
==== /node_modules/actually-json/index.json (0 errors) ====
|
||||
{}
|
||||
|
||||
==== /node_modules/actually-json/typed.d.json.ts (0 errors) ====
|
||||
declare const _default: {};
|
||||
export default _default;
|
||||
|
||||
==== /config.json (0 errors) ====
|
||||
{
|
||||
"version": 1
|
||||
}
|
||||
|
||||
==== /main.mts (6 errors) ====
|
||||
import { oops } from "not.json"; // Ok
|
||||
import moreOops from "actually-json"; // Error in nodenext
|
||||
import typed from "actually-json/typed"; // Error in nodenext
|
||||
|
||||
import config from "./config.json" with { type: "json" }; // Ok
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'.
|
||||
import { default as config1 } from "./config.json" with { type: "json" }; // Ok
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! 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 { 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'.
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'.
|
||||
import * as config3 from "./config.json" with { type: "json" };
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'.
|
||||
config3.version; // Error
|
||||
~~~~~~~
|
||||
!!! error TS2339: Property 'version' does not exist on type '{ default: { version: number; }; }'.
|
||||
config3.default; // Ok
|
||||
|
||||
==== /loosey.cts (2 errors) ====
|
||||
import config from "./config.json" with { type: "json" }; // Error
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2823: Import attributes are only supported when the '--module' option is set to 'esnext', 'nodenext', or 'preserve'.
|
||||
import config2 from "./config.json"; // Ok
|
||||
import { version } from "./config.json"; // Ok
|
||||
import * as config3 from "./config.json";
|
||||
config3.version; // Ok
|
||||
config3.default; // Error
|
||||
~~~~~~~
|
||||
!!! error TS2339: Property 'default' does not exist on type '{ version: number; }'.
|
||||
|
||||
@@ -26,10 +26,10 @@ export default _default;
|
||||
import { oops } from "not.json"; // Ok
|
||||
>oops : Symbol(oops, Decl(main.mts, 0, 8))
|
||||
|
||||
import moreOops from "actually-json"; // Error
|
||||
import moreOops from "actually-json"; // Error in nodenext
|
||||
>moreOops : Symbol(moreOops, Decl(main.mts, 1, 6))
|
||||
|
||||
import typed from "actually-json/typed"; // Error
|
||||
import typed from "actually-json/typed"; // Error in nodenext
|
||||
>typed : Symbol(typed, Decl(main.mts, 2, 6))
|
||||
|
||||
import config from "./config.json" with { type: "json" }; // Ok
|
||||
@@ -39,7 +39,7 @@ import { default as config1 } from "./config.json" with { type: "json" }; // Ok
|
||||
>default : Symbol(config, Decl(config.json, 0, 0))
|
||||
>config1 : Symbol(config1, Decl(main.mts, 5, 8))
|
||||
|
||||
import config2 from "./config.json"; // Error, no attribute
|
||||
import config2 from "./config.json"; // Error in nodenext, no attribute
|
||||
>config2 : Symbol(config2, Decl(main.mts, 6, 6))
|
||||
|
||||
import { version } from "./config.json" with { type: "json" }; // Error, named import
|
||||
@@ -38,11 +38,11 @@ import { oops } from "not.json"; // Ok
|
||||
>oops : (json: string) => any
|
||||
> : ^ ^^ ^^^^^
|
||||
|
||||
import moreOops from "actually-json"; // Error
|
||||
import moreOops from "actually-json"; // Error in nodenext
|
||||
>moreOops : {}
|
||||
> : ^^
|
||||
|
||||
import typed from "actually-json/typed"; // Error
|
||||
import typed from "actually-json/typed"; // Error in nodenext
|
||||
>typed : typeof typed
|
||||
> : ^^^^^^^^^^^^
|
||||
|
||||
@@ -60,7 +60,7 @@ import { default as config1 } from "./config.json" with { type: "json" }; // Ok
|
||||
>type : any
|
||||
> : ^^^
|
||||
|
||||
import config2 from "./config.json"; // Error, no attribute
|
||||
import config2 from "./config.json"; // Error in nodenext, no attribute
|
||||
>config2 : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -43,16 +43,16 @@
|
||||
|
||||
==== /main.mts (5 errors) ====
|
||||
import { oops } from "not.json"; // Ok
|
||||
import moreOops from "actually-json"; // Error
|
||||
import moreOops from "actually-json"; // Error in nodenext
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'.
|
||||
import typed from "actually-json/typed"; // Error
|
||||
import typed from "actually-json/typed"; // Error in nodenext
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to '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, no attribute
|
||||
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 { version } from "./config.json" with { type: "json" }; // Error, named import
|
||||
@@ -0,0 +1,79 @@
|
||||
//// [tests/cases/conformance/node/nodeModulesJson.ts] ////
|
||||
|
||||
=== /node_modules/not.json/index.d.ts ===
|
||||
export function oops(json: string): any;
|
||||
>oops : Symbol(oops, Decl(index.d.ts, 0, 0))
|
||||
>json : Symbol(json, Decl(index.d.ts, 0, 21))
|
||||
|
||||
=== /node_modules/actually-json/index.json ===
|
||||
|
||||
{}
|
||||
|
||||
=== /node_modules/actually-json/typed.d.json.ts ===
|
||||
declare const _default: {};
|
||||
>_default : Symbol(_default, Decl(typed.d.json.ts, 0, 13))
|
||||
|
||||
export default _default;
|
||||
>_default : Symbol(_default, Decl(typed.d.json.ts, 0, 13))
|
||||
|
||||
=== /config.json ===
|
||||
{
|
||||
"version": 1
|
||||
>"version" : Symbol("version", Decl(config.json, 0, 1))
|
||||
}
|
||||
|
||||
=== /main.mts ===
|
||||
import { oops } from "not.json"; // Ok
|
||||
>oops : Symbol(oops, Decl(main.mts, 0, 8))
|
||||
|
||||
import moreOops from "actually-json"; // Error in nodenext
|
||||
>moreOops : Symbol(moreOops, Decl(main.mts, 1, 6))
|
||||
|
||||
import typed from "actually-json/typed"; // Error in nodenext
|
||||
>typed : Symbol(typed, Decl(main.mts, 2, 6))
|
||||
|
||||
import config from "./config.json" with { type: "json" }; // Ok
|
||||
>config : Symbol(config, Decl(main.mts, 4, 6))
|
||||
|
||||
import { default as config1 } from "./config.json" with { type: "json" }; // Ok
|
||||
>default : Symbol(config, Decl(config.json, 0, 0))
|
||||
>config1 : Symbol(config1, Decl(main.mts, 5, 8))
|
||||
|
||||
import config2 from "./config.json"; // Error in nodenext, no attribute
|
||||
>config2 : Symbol(config2, Decl(main.mts, 6, 6))
|
||||
|
||||
import { version } from "./config.json" with { type: "json" }; // Error, named import
|
||||
>version : Symbol(version, Decl(main.mts, 7, 8))
|
||||
|
||||
import * as config3 from "./config.json" with { type: "json" };
|
||||
>config3 : Symbol(config3, Decl(main.mts, 8, 6))
|
||||
|
||||
config3.version; // Error
|
||||
>config3 : Symbol(config3, Decl(main.mts, 8, 6))
|
||||
|
||||
config3.default; // Ok
|
||||
>config3.default : Symbol("/config")
|
||||
>config3 : Symbol(config3, Decl(main.mts, 8, 6))
|
||||
>default : Symbol("/config")
|
||||
|
||||
=== /loosey.cts ===
|
||||
import config from "./config.json" with { type: "json" }; // Error
|
||||
>config : Symbol(config, Decl(loosey.cts, 0, 6))
|
||||
|
||||
import config2 from "./config.json"; // Ok
|
||||
>config2 : Symbol(config2, Decl(loosey.cts, 1, 6))
|
||||
|
||||
import { version } from "./config.json"; // Ok
|
||||
>version : Symbol(version, Decl(loosey.cts, 2, 8))
|
||||
|
||||
import * as config3 from "./config.json";
|
||||
>config3 : Symbol(config3, Decl(loosey.cts, 3, 6))
|
||||
|
||||
config3.version; // Ok
|
||||
>config3.version : Symbol(version, Decl(config.json, 0, 1))
|
||||
>config3 : Symbol(config3, Decl(loosey.cts, 3, 6))
|
||||
>version : Symbol(version, Decl(config.json, 0, 1))
|
||||
|
||||
config3.default; // Error
|
||||
>config3 : Symbol(config3, Decl(loosey.cts, 3, 6))
|
||||
|
||||
129
tests/baselines/reference/nodeModulesJson(module=nodenext).types
Normal file
129
tests/baselines/reference/nodeModulesJson(module=nodenext).types
Normal file
@@ -0,0 +1,129 @@
|
||||
//// [tests/cases/conformance/node/nodeModulesJson.ts] ////
|
||||
|
||||
=== /node_modules/not.json/index.d.ts ===
|
||||
export function oops(json: string): any;
|
||||
>oops : (json: string) => any
|
||||
> : ^ ^^ ^^^^^
|
||||
>json : string
|
||||
> : ^^^^^^
|
||||
|
||||
=== /node_modules/actually-json/index.json ===
|
||||
{}
|
||||
>{} : {}
|
||||
> : ^^
|
||||
|
||||
=== /node_modules/actually-json/typed.d.json.ts ===
|
||||
declare const _default: {};
|
||||
>_default : {}
|
||||
> : ^^
|
||||
|
||||
export default _default;
|
||||
>_default : {}
|
||||
> : ^^
|
||||
|
||||
=== /config.json ===
|
||||
{
|
||||
>{ "version": 1} : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
"version": 1
|
||||
>"version" : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
}
|
||||
|
||||
=== /main.mts ===
|
||||
import { oops } from "not.json"; // Ok
|
||||
>oops : (json: string) => any
|
||||
> : ^ ^^ ^^^^^
|
||||
|
||||
import moreOops from "actually-json"; // Error in nodenext
|
||||
>moreOops : {}
|
||||
> : ^^
|
||||
|
||||
import typed from "actually-json/typed"; // Error in nodenext
|
||||
>typed : typeof typed
|
||||
> : ^^^^^^^^^^^^
|
||||
|
||||
import config from "./config.json" with { type: "json" }; // Ok
|
||||
>config : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
>type : any
|
||||
> : ^^^
|
||||
|
||||
import { default as config1 } from "./config.json" with { type: "json" }; // Ok
|
||||
>default : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
>config1 : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
>type : any
|
||||
> : ^^^
|
||||
|
||||
import config2 from "./config.json"; // Error in nodenext, no attribute
|
||||
>config2 : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
import { version } from "./config.json" with { type: "json" }; // Error, named import
|
||||
>version : number
|
||||
> : ^^^^^^
|
||||
>type : any
|
||||
> : ^^^
|
||||
|
||||
import * as config3 from "./config.json" with { type: "json" };
|
||||
>config3 : { default: { version: number; }; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>type : any
|
||||
> : ^^^
|
||||
|
||||
config3.version; // Error
|
||||
>config3.version : any
|
||||
> : ^^^
|
||||
>config3 : { default: { version: number; }; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>version : any
|
||||
> : ^^^
|
||||
|
||||
config3.default; // Ok
|
||||
>config3.default : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
>config3 : { default: { version: number; }; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>default : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
=== /loosey.cts ===
|
||||
import config from "./config.json" with { type: "json" }; // Error
|
||||
>config : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
>type : any
|
||||
> : ^^^
|
||||
|
||||
import config2 from "./config.json"; // Ok
|
||||
>config2 : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
import { version } from "./config.json"; // Ok
|
||||
>version : number
|
||||
> : ^^^^^^
|
||||
|
||||
import * as config3 from "./config.json";
|
||||
>config3 : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
config3.version; // Ok
|
||||
>config3.version : number
|
||||
> : ^^^^^^
|
||||
>config3 : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
>version : number
|
||||
> : ^^^^^^
|
||||
|
||||
config3.default; // Error
|
||||
>config3.default : any
|
||||
> : ^^^
|
||||
>config3 : { version: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
>default : any
|
||||
> : ^^^
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @module: nodenext
|
||||
// @module: node16,nodenext
|
||||
// @resolveJsonModule: true
|
||||
// @noEmit: true
|
||||
|
||||
@@ -38,12 +38,12 @@ export default _default;
|
||||
|
||||
// @Filename: /main.mts
|
||||
import { oops } from "not.json"; // Ok
|
||||
import moreOops from "actually-json"; // Error
|
||||
import typed from "actually-json/typed"; // Error
|
||||
import moreOops from "actually-json"; // Error in nodenext
|
||||
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, no attribute
|
||||
import config2 from "./config.json"; // Error in nodenext, no attribute
|
||||
import { version } from "./config.json" with { type: "json" }; // Error, named import
|
||||
import * as config3 from "./config.json" with { type: "json" };
|
||||
config3.version; // Error
|
||||
|
||||
Reference in New Issue
Block a user