Skip to content

Commit 85d6bb6

Browse files
authored
Add new option "noUncheckedSideEffectImports" (#58941)
1 parent 79bd844 commit 85d6bb6

File tree

78 files changed

+985
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+985
-1
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,7 @@ import {
720720
isSetAccessorDeclaration,
721721
isShorthandAmbientModuleSymbol,
722722
isShorthandPropertyAssignment,
723+
isSideEffectImport,
723724
isSingleOrDoubleQuote,
724725
isSourceFile,
725726
isSourceFileJS,
@@ -1505,6 +1506,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
15051506
var noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis");
15061507
var useUnknownInCatchVariables = getStrictOptionValue(compilerOptions, "useUnknownInCatchVariables");
15071508
var exactOptionalPropertyTypes = compilerOptions.exactOptionalPropertyTypes;
1509+
var noUncheckedSideEffectImports = !!compilerOptions.noUncheckedSideEffectImports;
15081510

15091511
var checkBinaryExpression = createCheckBinaryExpression();
15101512
var emitResolver = createResolver();
@@ -4660,7 +4662,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
46604662
// merged symbol is module declaration symbol combined with all augmentations
46614663
return getMergedSymbol(sourceFile.symbol);
46624664
}
4663-
if (errorNode && moduleNotFoundError) {
4665+
if (errorNode && moduleNotFoundError && !isSideEffectImport(errorNode)) {
46644666
// report errors only if it was requested
46654667
error(errorNode, Diagnostics.File_0_is_not_a_module, sourceFile.fileName);
46664668
}
@@ -4765,6 +4767,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
47654767
}
47664768

47674769
function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, sourceFile: SourceFile, mode: ResolutionMode, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void {
4770+
if (isSideEffectImport(errorNode)) {
4771+
return;
4772+
}
4773+
47684774
let errorInfo: DiagnosticMessageChain | undefined;
47694775
if (!isExternalModuleNameRelative(moduleReference) && packageId) {
47704776
errorInfo = createModuleNotFoundChain(sourceFile, host, moduleReference, mode, packageId.name);
@@ -47246,6 +47252,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4724647252
}
4724747253
}
4724847254
}
47255+
else if (noUncheckedSideEffectImports && !importClause) {
47256+
void resolveExternalModuleName(node, node.moduleSpecifier);
47257+
}
4724947258
}
4725047259
checkImportAttributes(node);
4725147260
}

src/compiler/commandLineParser.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,15 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
12021202
category: Diagnostics.Modules,
12031203
description: Diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports,
12041204
},
1205+
{
1206+
name: "noUncheckedSideEffectImports",
1207+
type: "boolean",
1208+
affectsSemanticDiagnostics: true,
1209+
affectsBuildInfo: true,
1210+
category: Diagnostics.Modules,
1211+
description: Diagnostics.Check_side_effect_imports,
1212+
defaultValueDescription: false,
1213+
},
12051214

12061215
// Source Maps
12071216
{

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6388,6 +6388,10 @@
63886388
"category": "Message",
63896389
"code": 6805
63906390
},
6391+
"Check side effect imports.": {
6392+
"category": "Message",
6393+
"code": 6806
6394+
},
63916395

63926396
"one of:": {
63936397
"category": "Message",

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7418,6 +7418,7 @@ export interface CompilerOptions {
74187418
target?: ScriptTarget;
74197419
traceResolution?: boolean;
74207420
useUnknownInCatchVariables?: boolean;
7421+
noUncheckedSideEffectImports?: boolean;
74217422
resolveJsonModule?: boolean;
74227423
types?: string[];
74237424
/** Paths used to compute primary types search locations */

src/compiler/utilities.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ import {
287287
isIdentifier,
288288
isIdentifierStart,
289289
isIdentifierText,
290+
isImportDeclaration,
290291
isImportTypeNode,
291292
isInterfaceDeclaration,
292293
isJSDoc,
@@ -11758,3 +11759,9 @@ export function hasInferredType(node: Node): node is HasInferredType {
1175811759
return false;
1175911760
}
1176011761
}
11762+
11763+
/** @internal */
11764+
export function isSideEffectImport(node: Node): boolean {
11765+
const ancestor = findAncestor(node, isImportDeclaration);
11766+
return !!ancestor && !ancestor.importClause;
11767+
}

src/testRunner/unittests/tscWatch/programUpdates.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,4 +2245,40 @@ import { x } from "../b";`,
22452245
},
22462246
],
22472247
});
2248+
2249+
verifyTscWatch({
2250+
scenario,
2251+
subScenario: "when changing noUncheckedSideEffectImports of config file",
2252+
commandLineArgs: ["-w", "-p", ".", "--extendedDiagnostics"],
2253+
sys: () => {
2254+
const module1: File = {
2255+
path: `/user/username/projects/myproject/a.ts`,
2256+
content: `import "does-not-exist";`,
2257+
};
2258+
const config: File = {
2259+
path: `/user/username/projects/myproject/tsconfig.json`,
2260+
content: jsonToReadableText({
2261+
compilerOptions: {
2262+
noUncheckedSideEffectImports: false,
2263+
},
2264+
}),
2265+
};
2266+
return createWatchedSystem([module1, config, libFile], { currentDirectory: "/user/username/projects/myproject" });
2267+
},
2268+
edits: [
2269+
{
2270+
caption: "Change noUncheckedSideEffectImports to true",
2271+
edit: sys =>
2272+
sys.writeFile(
2273+
`/user/username/projects/myproject/tsconfig.json`,
2274+
jsonToReadableText({
2275+
compilerOptions: {
2276+
noUncheckedSideEffectImports: true,
2277+
},
2278+
}),
2279+
),
2280+
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
2281+
},
2282+
],
2283+
});
22482284
});

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7017,6 +7017,7 @@ declare namespace ts {
70177017
target?: ScriptTarget;
70187018
traceResolution?: boolean;
70197019
useUnknownInCatchVariables?: boolean;
7020+
noUncheckedSideEffectImports?: boolean;
70207021
resolveJsonModule?: boolean;
70217022
types?: string[];
70227023
/** Paths used to compute primary types search locations */

tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
4040
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
4141
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42+
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
4243
// "resolveJsonModule": true, /* Enable importing .json files. */
4344
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
4445
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"compilerOptions": {
3+
"noUncheckedSideEffectImports": true
4+
}
5+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
//// [sideEffectImports1.ts]
4+
import "does-not-exist";
5+
import "./does-not-exist-either";
6+
import "./does-not-exist-either.js";
7+
8+
9+
//// [sideEffectImports1.js]
10+
"use strict";
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
require("does-not-exist");
13+
require("./does-not-exist-either");
14+
require("./does-not-exist-either.js");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
=== sideEffectImports1.ts ===
4+
5+
import "does-not-exist";
6+
import "./does-not-exist-either";
7+
import "./does-not-exist-either.js";
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
=== sideEffectImports1.ts ===
4+
5+
import "does-not-exist";
6+
import "./does-not-exist-either";
7+
import "./does-not-exist-either.js";
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
sideEffectImports1.ts(1,8): error TS2307: Cannot find module 'does-not-exist' or its corresponding type declarations.
2+
sideEffectImports1.ts(2,8): error TS2307: Cannot find module './does-not-exist-either' or its corresponding type declarations.
3+
sideEffectImports1.ts(3,8): error TS2307: Cannot find module './does-not-exist-either.js' or its corresponding type declarations.
4+
5+
6+
==== sideEffectImports1.ts (3 errors) ====
7+
import "does-not-exist";
8+
~~~~~~~~~~~~~~~~
9+
!!! error TS2307: Cannot find module 'does-not-exist' or its corresponding type declarations.
10+
import "./does-not-exist-either";
11+
~~~~~~~~~~~~~~~~~~~~~~~~~
12+
!!! error TS2307: Cannot find module './does-not-exist-either' or its corresponding type declarations.
13+
import "./does-not-exist-either.js";
14+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15+
!!! error TS2307: Cannot find module './does-not-exist-either.js' or its corresponding type declarations.
16+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
//// [sideEffectImports1.ts]
4+
import "does-not-exist";
5+
import "./does-not-exist-either";
6+
import "./does-not-exist-either.js";
7+
8+
9+
//// [sideEffectImports1.js]
10+
"use strict";
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
require("does-not-exist");
13+
require("./does-not-exist-either");
14+
require("./does-not-exist-either.js");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
=== sideEffectImports1.ts ===
4+
5+
import "does-not-exist";
6+
import "./does-not-exist-either";
7+
import "./does-not-exist-either.js";
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
=== sideEffectImports1.ts ===
4+
5+
import "does-not-exist";
6+
import "./does-not-exist-either";
7+
import "./does-not-exist-either.js";
8+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
//// [sideEffectImports1.ts]
4+
import "does-not-exist";
5+
import "./does-not-exist-either";
6+
import "./does-not-exist-either.js";
7+
8+
9+
//// [sideEffectImports1.js]
10+
"use strict";
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
require("does-not-exist");
13+
require("./does-not-exist-either");
14+
require("./does-not-exist-either.js");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
=== sideEffectImports1.ts ===
4+
5+
import "does-not-exist";
6+
import "./does-not-exist-either";
7+
import "./does-not-exist-either.js";
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//// [tests/cases/compiler/sideEffectImports1.ts] ////
2+
3+
=== sideEffectImports1.ts ===
4+
5+
import "does-not-exist";
6+
import "./does-not-exist-either";
7+
import "./does-not-exist-either.js";
8+

0 commit comments

Comments
 (0)