fix(common): reflect input type in NgIf context (#33997)

Fixes the content of `NgIf` being typed to any.

Fixes #31556.

PR Close #33997
This commit is contained in:
crisbeto
2019-11-29 23:11:28 +01:00
committed by Miško Hevery
parent a6b6d74c00
commit 02958c07f6
4 changed files with 70 additions and 25 deletions

View File

@ -149,14 +149,14 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef, ɵstri
* @publicApi
*/
@Directive({selector: '[ngIf]'})
export class NgIf {
private _context: NgIfContext = new NgIfContext();
private _thenTemplateRef: TemplateRef<NgIfContext>|null = null;
private _elseTemplateRef: TemplateRef<NgIfContext>|null = null;
private _thenViewRef: EmbeddedViewRef<NgIfContext>|null = null;
private _elseViewRef: EmbeddedViewRef<NgIfContext>|null = null;
export class NgIf<T> {
private _context: NgIfContext<T> = new NgIfContext<T>();
private _thenTemplateRef: TemplateRef<NgIfContext<T>>|null = null;
private _elseTemplateRef: TemplateRef<NgIfContext<T>>|null = null;
private _thenViewRef: EmbeddedViewRef<NgIfContext<T>>|null = null;
private _elseViewRef: EmbeddedViewRef<NgIfContext<T>>|null = null;
constructor(private _viewContainer: ViewContainerRef, templateRef: TemplateRef<NgIfContext>) {
constructor(private _viewContainer: ViewContainerRef, templateRef: TemplateRef<NgIfContext<T>>) {
this._thenTemplateRef = templateRef;
}
@ -164,7 +164,7 @@ export class NgIf {
* The Boolean expression to evaluate as the condition for showing a template.
*/
@Input()
set ngIf(condition: any) {
set ngIf(condition: T) {
this._context.$implicit = this._context.ngIf = condition;
this._updateView();
}
@ -173,7 +173,7 @@ export class NgIf {
* A template to show if the condition expression evaluates to true.
*/
@Input()
set ngIfThen(templateRef: TemplateRef<NgIfContext>|null) {
set ngIfThen(templateRef: TemplateRef<NgIfContext<T>>|null) {
assertTemplate('ngIfThen', templateRef);
this._thenTemplateRef = templateRef;
this._thenViewRef = null; // clear previous view if any.
@ -184,7 +184,7 @@ export class NgIf {
* A template to show if the condition expression evaluates to false.
*/
@Input()
set ngIfElse(templateRef: TemplateRef<NgIfContext>|null) {
set ngIfElse(templateRef: TemplateRef<NgIfContext<T>>|null) {
assertTemplate('ngIfElse', templateRef);
this._elseTemplateRef = templateRef;
this._elseViewRef = null; // clear previous view if any.
@ -225,14 +225,22 @@ export class NgIf {
* narrow its type, which allows the strictNullChecks feature of TypeScript to work with `NgIf`.
*/
static ngTemplateGuard_ngIf: 'binding';
/**
* Asserts the correct type of the context for the template that `NgIf` will render.
*
* The presence of this method is a signal to the Ivy template type-check compiler that the
* `NgIf` structural directive renders its template with a specific context type.
*/
static ngTemplateContextGuard<T>(dir: NgIf<T>, ctx: any): ctx is NgIfContext<T> { return true; }
}
/**
* @publicApi
*/
export class NgIfContext {
public $implicit: any = null;
public ngIf: any = null;
export class NgIfContext<T> {
public $implicit: T = null !;
public ngIf: T = null !;
}
function assertTemplate(property: string, templateRef: TemplateRef<any>| null): void {