diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2e975397c1a49..00a19b05c3e4e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -62,6 +62,7 @@ import { canHaveModifiers, canHaveModuleSpecifier, canHaveSymbol, + canIncludeBindAndCheckDiagnsotics, canUsePropertyAccess, cartesianProduct, CaseBlock, @@ -49029,7 +49030,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function calculateNodeCheckFlagWorker(node: Node, flag: LazyNodeCheckFlags) { - if (!compilerOptions.noCheck) { + if (!compilerOptions.noCheck && canIncludeBindAndCheckDiagnsotics(getSourceFileOfNode(node), compilerOptions)) { // Unless noCheck is passed, assume calculation of node check flags has been done eagerly. // This saves needing to mark up where in the eager traversal certain results are "done", // just to reconcile the eager and lazy results. This wouldn't be hard if an eager typecheck diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 539190c63c336..a1d94788413b2 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -21,6 +21,7 @@ import { CallExpression, CallSignatureDeclaration, canHaveLocals, + canIncludeBindAndCheckDiagnsotics, CaseBlock, CaseClause, CaseOrDefaultClause, @@ -800,9 +801,14 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi return; } - if (compilerOptions.noCheck) { - (isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach(markLinkedReferences); - } + (isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach( + sourceFile => { + if ( + compilerOptions.noCheck || + !canIncludeBindAndCheckDiagnsotics(sourceFile, compilerOptions) + ) markLinkedReferences(sourceFile); + }, + ); // Transform the source files const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false); @@ -859,15 +865,19 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi const filesForEmit = forceDtsEmit ? sourceFiles : filter(sourceFiles, isSourceFileNotJson); // Setup and perform the transformation to retrieve declarations from the input files const inputListOrBundle = compilerOptions.outFile ? [factory.createBundle(filesForEmit)] : filesForEmit; - if ( - (emitOnly && !getEmitDeclarations(compilerOptions)) || - compilerOptions.noCheck || - emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit) - ) { - // Checker wont collect the linked aliases since thats only done when declaration is enabled and checking is performed. - // Do that here when emitting only dts files - filesForEmit.forEach(collectLinkedAliases); - } + // Checker wont collect the linked aliases since thats only done when declaration is enabled and checking is performed. + // Do that here when emitting only dts files + filesForEmit.forEach(sourceFile => { + if ( + (emitOnly && !getEmitDeclarations(compilerOptions)) || + compilerOptions.noCheck || + emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit) || + !canIncludeBindAndCheckDiagnsotics(sourceFile, compilerOptions) + ) { + collectLinkedAliases(sourceFile); + } + }); + const declarationTransform = transformNodes(resolver, host, factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false); if (length(declarationTransform.diagnostics)) { for (const diagnostic of declarationTransform.diagnostics!) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 0402c1bba985d..84093eb491939 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3016,22 +3016,19 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg const isJs = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX; const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options); const isPlainJs = isPlainJsFile(sourceFile, options.checkJs); - const isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false; // By default, only type-check .ts, .tsx, Deferred, plain JS, checked JS and External // - plain JS: .js files with no // ts-check and checkJs: undefined // - check JS: .js files with either // ts-check or checkJs: true // - external: files that are added by plugins - const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX - || sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred); - let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; - let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; + let bindDiagnostics = sourceFile.bindDiagnostics; + let checkDiagnostics = typeChecker.getDiagnostics(sourceFile, cancellationToken); if (isPlainJs) { bindDiagnostics = filter(bindDiagnostics, d => plainJSErrors.has(d.code)); checkDiagnostics = filter(checkDiagnostics, d => plainJSErrors.has(d.code)); } // skip ts-expect-error errors in plain JS files, and skip JSDoc errors except in checked JS - return getMergedBindAndCheckDiagnostics(sourceFile, includeBindAndCheckDiagnostics && !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined); + return getMergedBindAndCheckDiagnostics(sourceFile, !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined); }); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4cf5f0082cd20..721500b896b21 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -10082,7 +10082,28 @@ export function skipTypeChecking(sourceFile: SourceFile, options: CompilerOption return (options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) || options.noCheck || - host.isSourceOfProjectReferenceRedirect(sourceFile.fileName); + host.isSourceOfProjectReferenceRedirect(sourceFile.fileName) || + !canIncludeBindAndCheckDiagnsotics(sourceFile, options); +} + +/** @internal */ +export function canIncludeBindAndCheckDiagnsotics(sourceFile: SourceFile, options: CompilerOptions) { + if (!!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false) return false; + if ( + sourceFile.scriptKind === ScriptKind.TS || + sourceFile.scriptKind === ScriptKind.TSX || + sourceFile.scriptKind === ScriptKind.External + ) return true; + + const isJs = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX; + const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options); + const isPlainJs = isPlainJsFile(sourceFile, options.checkJs); + + // By default, only type-check .ts, .tsx, Deferred, plain JS, checked JS and External + // - plain JS: .js files with no // ts-check and checkJs: undefined + // - check JS: .js files with either // ts-check or checkJs: true + // - external: files that are added by plugins + return isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred; } /** @internal */