fix(ivy): include directive base class metadata when generating TCBs (#29698)

Previously the template type-checking code only considered the metadata of
directive classes actually referenced in the template. If those directives
had base classes, any inputs/outputs/etc of the base classes were not
tracked when generating the TCB. This resulted in bindings to those inputs
being incorrectly attributed to the host component or element.

This commit uses the new metadata package to follow directive inheritance
chains and use the full metadata for a directive for TCB generation.

Testing strategy: Template type-checking tests included.

PR Close #29698
This commit is contained in:
Alex Rickabaugh
2019-04-01 14:20:34 -07:00
committed by Ben Lesh
parent 9277afce61
commit cd1277cfb7
13 changed files with 230 additions and 23 deletions

View File

@ -164,4 +164,46 @@ describe('ngtsc type checking', () => {
expect(diags.length).toBe(1);
expect(diags[0].messageText).toContain('does_not_exist');
});
it('should properly type-check inherited directives', () => {
env.write('test.ts', `
import {Component, Directive, Input, NgModule} from '@angular/core';
@Directive({
selector: '[base]',
})
class BaseDir {
@Input() fromBase!: string;
}
@Directive({
selector: '[child]',
})
class ChildDir extends BaseDir {
@Input() fromChild!: boolean;
}
@Component({
selector: 'test',
template: '<div child [fromBase]="3" [fromChild]="4"></div>',
})
class TestCmp {}
@NgModule({
declarations: [TestCmp, ChildDir],
})
class Module {}
`);
const diags = env.driveDiagnostics();
expect(diags.length).toBe(2);
// Error from the binding to [fromBase].
expect(diags[0].messageText)
.toBe(`Type 'number' is not assignable to type 'string | undefined'.`);
// Error from the binding to [fromChild].
expect(diags[1].messageText)
.toBe(`Type 'number' is not assignable to type 'boolean | undefined'.`);
});
});