diff --git a/packages/compiler-cli/src/ngtsc/metadata/src/inheritance.ts b/packages/compiler-cli/src/ngtsc/metadata/src/inheritance.ts index bb9e9bc7b0..c6265188d1 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/src/inheritance.ts +++ b/packages/compiler-cli/src/ngtsc/metadata/src/inheritance.ts @@ -27,6 +27,7 @@ export function flattenInheritedDirectiveMetadata( let inputs: {[key: string]: string | [string, string]} = {}; let outputs: {[key: string]: string} = {}; + let coercedInputFields = new Set(); let isDynamic = false; const addMetadata = (meta: DirectiveMeta): void => { @@ -43,6 +44,10 @@ export function flattenInheritedDirectiveMetadata( } inputs = {...inputs, ...meta.inputs}; outputs = {...outputs, ...meta.outputs}; + + for (const coercedInputField of meta.coercedInputFields) { + coercedInputFields.add(coercedInputField); + } }; addMetadata(topMeta); @@ -51,6 +56,7 @@ export function flattenInheritedDirectiveMetadata( ...topMeta, inputs, outputs, + coercedInputFields, baseClass: isDynamic ? 'dynamic' : null, }; } diff --git a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts index 39b7b48458..76da4e324a 100644 --- a/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts +++ b/packages/compiler-cli/test/ngtsc/template_typecheck_spec.ts @@ -1123,9 +1123,7 @@ export declare class AnimationEvent { describe('input coercion', () => { beforeEach(() => { - env.tsconfig({ - 'fullTemplateTypeCheck': true, - }); + env.tsconfig({fullTemplateTypeCheck: true, strictInputTypes: true}); env.write('node_modules/@angular/material/index.d.ts', ` import * as i0 from '@angular/core'; @@ -1164,10 +1162,42 @@ export declare class AnimationEvent { expect(diags.length).toBe(0); }); + it('should apply coercion members of base classes', () => { + env.write('test.ts', ` + import {Component, Directive, Input, NgModule} from '@angular/core'; + + @Directive() + export class BaseDir { + @Input() + value: string; + + static ngAcceptInputType_value: string|number; + } + + @Directive({ + selector: '[dir]', + }) + export class MyDir extends BaseDir {} + + @Component({ + selector: 'blah', + template: '', + }) + export class FooCmp { + someNumber = 3; + } + + @NgModule({ + declarations: [MyDir, FooCmp], + }) + export class FooModule {} + `); + const diags = env.driveDiagnostics(); + expect(diags.length).toBe(0); + }); + it('should give an error if the binding expression type is not accepted by the coercion function', () => { - env.tsconfig({fullTemplateTypeCheck: true, strictInputTypes: true}); - env.write('test.ts', ` import {Component, NgModule} from '@angular/core'; import {MatInputModule} from '@angular/material';