diff --git a/packages/compiler-cli/src/ngtsc/diagnostics/src/code.ts b/packages/compiler-cli/src/ngtsc/diagnostics/src/code.ts index 4a2e84ef60..cceeb2cc88 100644 --- a/packages/compiler-cli/src/ngtsc/diagnostics/src/code.ts +++ b/packages/compiler-cli/src/ngtsc/diagnostics/src/code.ts @@ -39,6 +39,7 @@ export enum ErrorCode { SYMBOL_EXPORTED_UNDER_DIFFERENT_NAME = 3002, CONFIG_FLAT_MODULE_NO_INDEX = 4001, + CONFIG_STRICT_TEMPLATES_IMPLIES_FULL_TEMPLATE_TYPECHECK = 4002, /** * Raised when a host expression has a parse error, such as a host listener or host binding diff --git a/packages/compiler-cli/src/ngtsc/program.ts b/packages/compiler-cli/src/ngtsc/program.ts index b2bd027fc0..34255a07eb 100644 --- a/packages/compiler-cli/src/ngtsc/program.ts +++ b/packages/compiler-cli/src/ngtsc/program.ts @@ -82,6 +82,11 @@ export class NgtscProgram implements api.Program { verifySupportedTypeScriptVersion(); } + const incompatibleTypeCheckOptionsDiagnostic = verifyCompatibleTypeCheckOptions(options); + if (incompatibleTypeCheckOptionsDiagnostic !== null) { + this.constructionDiagnostics.push(incompatibleTypeCheckOptionsDiagnostic); + } + if (shouldEnablePerfTracing(options)) { this.perfTracker = PerfTracker.zeroedToNow(); this.perfRecorder = this.perfTracker; @@ -829,6 +834,37 @@ function isAngularCorePackage(program: ts.Program): boolean { }); } +/** + * Since "strictTemplates" is a true superset of type checking capabilities compared to + * "strictTemplateTypeCheck", it is required that the latter is not explicitly disabled if the + * former is enabled. + */ +function verifyCompatibleTypeCheckOptions(options: api.CompilerOptions): ts.Diagnostic|null { + if (options.fullTemplateTypeCheck === false && options.strictTemplates === true) { + return { + category: ts.DiagnosticCategory.Error, + code: ngErrorCode(ErrorCode.CONFIG_STRICT_TEMPLATES_IMPLIES_FULL_TEMPLATE_TYPECHECK), + file: undefined, + start: undefined, + length: undefined, + messageText: + `Angular compiler option "strictTemplates" is enabled, however "fullTemplateTypeCheck" is disabled. + +Having the "strictTemplates" flag enabled implies that "fullTemplateTypeCheck" is also enabled, so +the latter can not be explicitly disabled. + +One of the following actions is required: +1. Remove the "fullTemplateTypeCheck" option. +2. Remove "strictTemplates" or set it to 'false'. + +More information about the template type checking compiler options can be found in the documentation: +https://v9.angular.io/guide/template-typecheck#template-type-checking`, + }; + } + + return null; +} + export class ReferenceGraphAdapter implements ReferencesRegistry { constructor(private graph: ReferenceGraph) {} diff --git a/packages/compiler-cli/src/transformers/api.ts b/packages/compiler-cli/src/transformers/api.ts index 48c178363e..11eed7c2ad 100644 --- a/packages/compiler-cli/src/transformers/api.ts +++ b/packages/compiler-cli/src/transformers/api.ts @@ -114,6 +114,8 @@ export interface CompilerOptions extends ts.CompilerOptions { * whether embedded views are checked. * * For maximum type-checking, set this to `true`, and set `strictTemplates` to `true`. + * + * It is an error for this flag to be `false`, while `strictTemplates` is set to `true`. */ fullTemplateTypeCheck?: boolean; diff --git a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts index 49f31c2ad4..0a2cc9d64b 100644 --- a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts +++ b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts @@ -1552,6 +1552,41 @@ export declare class AnimationEvent { }); }); }); + + describe('option compatibility verification', () => { + beforeEach(() => env.write('index.ts', `export const a = 1;`)); + + it('should error if "fullTemplateTypeCheck" is false when "strictTemplates" is true', () => { + env.tsconfig({fullTemplateTypeCheck: false, strictTemplates: true}); + + const diags = env.driveDiagnostics(); + expect(diags.length).toBe(1); + expect(diags[0].messageText) + .toContain( + 'Angular compiler option "strictTemplates" is enabled, however "fullTemplateTypeCheck" is disabled.'); + }); + it('should not error if "fullTemplateTypeCheck" is false when "strictTemplates" is false', + () => { + env.tsconfig({fullTemplateTypeCheck: false, strictTemplates: false}); + + const diags = env.driveDiagnostics(); + expect(diags.length).toBe(0); + }); + it('should not error if "fullTemplateTypeCheck" is not set when "strictTemplates" is true', + () => { + env.tsconfig({strictTemplates: true}); + + const diags = env.driveDiagnostics(); + expect(diags.length).toBe(0); + }); + it('should not error if "fullTemplateTypeCheck" is true set when "strictTemplates" is true', + () => { + env.tsconfig({strictTemplates: true}); + + const diags = env.driveDiagnostics(); + expect(diags.length).toBe(0); + }); + }); }); });