bvdb
bvdb

Reputation: 24750

TemplateRef requires type argument

Component HTML:

<ng-template #content/> </ng-template>

Component TS:

@ViewChild('content')
public content: TemplateRef;

Visual Studio message:

[ts] Generic type 'TemplateRef<C>' requires 1 type argument(s)

Am I supposed to just make it TemplateRef<any> ? Code samples never seem to specify the generics though. Is this new ?

Upvotes: 25

Views: 19526

Answers (5)

0xFF
0xFF

Reputation: 46

To avoid linter warnings, you can use unknown type instead of any.

Upvotes: 1

vhbazan
vhbazan

Reputation: 1417

In case you want to use Angular best practices and don't use "any" as a type for the TemplateRef<C> when passing a reference to a HTML element you can use the generic interface type for html elements: Element

Component TS:

public content: TemplateRef<Element>;

Upvotes: 9

Sheed
Sheed

Reputation: 619

Based on Nexaddo post, I will elaborate here. Given a component:

    @Component({
      selector: 'app-modal',
      templateUrl: './my.component.html',
      styleUrls: ['./my.component.css']
    })
    export class MyComponent implements OnInit {
      data = "oldData";
      @ViewChild() template0:TemplateRef<any>;
      constructor() { }
    
      ngOnInit() {
      }
    
    }

TempalteRef is a template reference as its name implies. @ViewChild() is just there to say "the template is in my view", you could use @ContentChild() or @Input() if you passed the template from the call to MyComponent.

When you summon it in your component template (./my.component.html here), in most cases you would do so :

    <ng-template #template0>
        <p>Lorem Ipsum...</p>
        <p>{{data}}</p>
        <p>Lorem Ipsum...</p>
    </ng-template>
    <ng-container *ngTemplateOutlet="template0">
        
    </ng-container>

Here, the call to template0 will interpolate data from the component context, because all templates inside it share the same context. But you could specify another context like so:

    <ng-container *ngTemplateOutlet="template0;context=newCtx">
        
    </ng-container>

From:

    export class MyComponent implements OnInit {
      data = "oldData";
      newCtx = {data = "newData"};
      ...
    }

Like so, the "newData" will be interpolated instead of "oldData".

Now, you do realize newCtx has any as a type, and that's where TemplateRef<any> comes from. In most cases you might be fine with it, but for the sake of reusability or just for compiler check, you could precise which class this context should be: TemplateRef<CustomContextClass>, and you'd have to declare your context like so : newCtx:CustomContextClass (or any child class of CustomContextClass naturally).

src: https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/ and https://blog.mgechev.com/2017/10/01/angular-template-ref-dynamic-scoping-custom-templates/

Upvotes: 8

ndraiman
ndraiman

Reputation: 691

You can use TempalteRef<any> and in almost all use cases you'll be fine.

But if you want more information, you can read this blog post (specifically the "Dynamic Scoping in Angular" section) by Minko Gechev.

Upvotes: 8

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657466

In Angular Material 2 they used

TemplateRef<any>

everywhere https://github.com/angular/material2/search?utf8=%E2%9C%93&q=templateref&type=

I haven't seen anything where this type parameter would be relevant.

Upvotes: 19

Related Questions