Typing Angular PrimeNg templates

Alain Boudard
3 min readJan 26, 2023

How to bring type checking to our Angular templates that use the PrimeNg library components and customize their display with the built-in ngTemplateOutlet feature.

This is merely an application of existing content from Josh Morony. He made a video about this here, video based on a PR itself.

Now, Josh video is about building your own Table component and customize it with all the tools Angular is providing, like the now famous ngTemplateOutlet.

Our point here is to apply the method to existing component library that is PrimeNg Table. By extension, we would be able to use the technique with any PrimeNg component that exposes ng-template customization.

So for a stater we create a new Angular application

ng new prime-template-context-guard --style scss --routing

Now we simply install PrimeNg

npm i primeng@14 primeicons@6

And apply the css of PrimeNg in angular.json

"styles": [
"src/styles.scss",
"node_modules/primeicons/primeicons.css",
"node_modules/primeng/resources/themes/lara-light-blue/theme.css",
"node_modules/primeng/resources/primeng.min.css"
],

Then we create a simple Table inside a component :

<p-table [value]="products" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>

Now, based on what we learnt from the video and the official Angular docs, we create the directive that will use the ngTemplateContextGuard :

ng g directive directives/table-row

In the directive we plan to consume the data injected in the p-table component and use it to type the context of the ng-template. So we create an interface for this context and the directive will expose a static method ngTemplateContextGuard :

import { Directive, Input } from '@angular/core';

interface TableRowTemplateContext<Titem extends object> {
$implicit: Titem;
}

@Directive({
selector: 'ng-template[appTableRow]'
})
export class TableRowDirective<Titem extends object> {

@Input('appTableRow') items!: Titem[];

static ngTemplateContextGuard<TContextItem extends object>(
dir: TableRowDirective<TContextItem>,
ctx: unknown
): ctx is TableRowTemplateContext<TContextItem> {
return true;
}

}

We apply the directive to the appropriate ng-template in the p-table :

<ng-template [appTableRow]="products" pTemplate="body" let-product>

And then we have exactly what we need : strictly typed context data in the PrimeNg Table component :

Type checking for Angular ng-template.

And here it is. Hopefully this could land in PrimeNg since it’s a great compoment library, that would only be nice to have it native.

Here is the github for this article :

And here are some great articles about using this kind of directive in your own components.

Next part : typing additional properties like columns.

--

--