Skip to content

Commit

Permalink
Add new option "noUncheckedSideEffectImports" (#58941)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakebailey authored Jul 20, 2024
1 parent 79bd844 commit 85d6bb6
Show file tree
Hide file tree
Showing 78 changed files with 985 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ import {
isSetAccessorDeclaration,
isShorthandAmbientModuleSymbol,
isShorthandPropertyAssignment,
isSideEffectImport,
isSingleOrDoubleQuote,
isSourceFile,
isSourceFileJS,
Expand Down Expand Up @@ -1505,6 +1506,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
var noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis");
var useUnknownInCatchVariables = getStrictOptionValue(compilerOptions, "useUnknownInCatchVariables");
var exactOptionalPropertyTypes = compilerOptions.exactOptionalPropertyTypes;
var noUncheckedSideEffectImports = !!compilerOptions.noUncheckedSideEffectImports;

var checkBinaryExpression = createCheckBinaryExpression();
var emitResolver = createResolver();
Expand Down Expand Up @@ -4660,7 +4662,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// merged symbol is module declaration symbol combined with all augmentations
return getMergedSymbol(sourceFile.symbol);
}
if (errorNode && moduleNotFoundError) {
if (errorNode && moduleNotFoundError && !isSideEffectImport(errorNode)) {
// report errors only if it was requested
error(errorNode, Diagnostics.File_0_is_not_a_module, sourceFile.fileName);
}
Expand Down Expand Up @@ -4765,6 +4767,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, sourceFile: SourceFile, mode: ResolutionMode, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void {
if (isSideEffectImport(errorNode)) {
return;
}

let errorInfo: DiagnosticMessageChain | undefined;
if (!isExternalModuleNameRelative(moduleReference) && packageId) {
errorInfo = createModuleNotFoundChain(sourceFile, host, moduleReference, mode, packageId.name);
Expand Down Expand Up @@ -47246,6 +47252,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
}
else if (noUncheckedSideEffectImports && !importClause) {
void resolveExternalModuleName(node, node.moduleSpecifier);
}
}
checkImportAttributes(node);
}
Expand Down
9 changes: 9 additions & 0 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,15 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
category: Diagnostics.Modules,
description: Diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports,
},
{
name: "noUncheckedSideEffectImports",
type: "boolean",
affectsSemanticDiagnostics: true,
affectsBuildInfo: true,
category: Diagnostics.Modules,
description: Diagnostics.Check_side_effect_imports,
defaultValueDescription: false,
},

// Source Maps
{
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -6388,6 +6388,10 @@
"category": "Message",
"code": 6805
},
"Check side effect imports.": {
"category": "Message",
"code": 6806
},

"one of:": {
"category": "Message",
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7418,6 +7418,7 @@ export interface CompilerOptions {
target?: ScriptTarget;
traceResolution?: boolean;
useUnknownInCatchVariables?: boolean;
noUncheckedSideEffectImports?: boolean;
resolveJsonModule?: boolean;
types?: string[];
/** Paths used to compute primary types search locations */
Expand Down
7 changes: 7 additions & 0 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ import {
isIdentifier,
isIdentifierStart,
isIdentifierText,
isImportDeclaration,
isImportTypeNode,
isInterfaceDeclaration,
isJSDoc,
Expand Down Expand Up @@ -11758,3 +11759,9 @@ export function hasInferredType(node: Node): node is HasInferredType {
return false;
}
}

/** @internal */
export function isSideEffectImport(node: Node): boolean {
const ancestor = findAncestor(node, isImportDeclaration);
return !!ancestor && !ancestor.importClause;
}
36 changes: 36 additions & 0 deletions src/testRunner/unittests/tscWatch/programUpdates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2245,4 +2245,40 @@ import { x } from "../b";`,
},
],
});

verifyTscWatch({
scenario,
subScenario: "when changing noUncheckedSideEffectImports of config file",
commandLineArgs: ["-w", "-p", ".", "--extendedDiagnostics"],
sys: () => {
const module1: File = {
path: `/user/username/projects/myproject/a.ts`,
content: `import "does-not-exist";`,
};
const config: File = {
path: `/user/username/projects/myproject/tsconfig.json`,
content: jsonToReadableText({
compilerOptions: {
noUncheckedSideEffectImports: false,
},
}),
};
return createWatchedSystem([module1, config, libFile], { currentDirectory: "/user/username/projects/myproject" });
},
edits: [
{
caption: "Change noUncheckedSideEffectImports to true",
edit: sys =>
sys.writeFile(
`/user/username/projects/myproject/tsconfig.json`,
jsonToReadableText({
compilerOptions: {
noUncheckedSideEffectImports: true,
},
}),
),
timeouts: sys => sys.runQueuedTimeoutCallbacks(),
},
],
});
});
1 change: 1 addition & 0 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7017,6 +7017,7 @@ declare namespace ts {
target?: ScriptTarget;
traceResolution?: boolean;
useUnknownInCatchVariables?: boolean;
noUncheckedSideEffectImports?: boolean;
resolveJsonModule?: boolean;
types?: string[];
/** Paths used to compute primary types search locations */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"noUncheckedSideEffectImports": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

//// [sideEffectImports1.ts]
import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";


//// [sideEffectImports1.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("does-not-exist");
require("./does-not-exist-either");
require("./does-not-exist-either.js");
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

=== sideEffectImports1.ts ===

import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

=== sideEffectImports1.ts ===

import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
sideEffectImports1.ts(1,8): error TS2307: Cannot find module 'does-not-exist' or its corresponding type declarations.
sideEffectImports1.ts(2,8): error TS2307: Cannot find module './does-not-exist-either' or its corresponding type declarations.
sideEffectImports1.ts(3,8): error TS2307: Cannot find module './does-not-exist-either.js' or its corresponding type declarations.


==== sideEffectImports1.ts (3 errors) ====
import "does-not-exist";
~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'does-not-exist' or its corresponding type declarations.
import "./does-not-exist-either";
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module './does-not-exist-either' or its corresponding type declarations.
import "./does-not-exist-either.js";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module './does-not-exist-either.js' or its corresponding type declarations.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

//// [sideEffectImports1.ts]
import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";


//// [sideEffectImports1.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("does-not-exist");
require("./does-not-exist-either");
require("./does-not-exist-either.js");
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

=== sideEffectImports1.ts ===

import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

=== sideEffectImports1.ts ===

import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

//// [sideEffectImports1.ts]
import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";


//// [sideEffectImports1.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("does-not-exist");
require("./does-not-exist-either");
require("./does-not-exist-either.js");
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

=== sideEffectImports1.ts ===

import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [tests/cases/compiler/sideEffectImports1.ts] ////

=== sideEffectImports1.ts ===

import "does-not-exist";
import "./does-not-exist-either";
import "./does-not-exist-either.js";

Loading

0 comments on commit 85d6bb6

Please sign in to comment.