Strongly Typed ngTemplateOutlet

cover image

The ngTemplateOutlet can be used to project content into a component and therefore generic components such as tables commonly use them. But achieving strong typing is not trivial at all and needs some little TypeScript tricks.

Loosely Typed Table

Below, you can see the code for a very basic generic table that leverages the ngTemplateOutlet to be reusable for various use-cases.

<div class="overflow-x-auto relative">
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400 table-fixed">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<ng-container
*ngTemplateOutlet="tableHead"
></ng-container>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of data" class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<ng-container
*ngTemplateOutlet="tableRow; context: { $implicit: row }"
></ng-container>
</tr>
</tbody>
</table>
</div>
export class TableComponent {
@Input() data!: any;
@ContentChild('tableHead') tableHead!: TemplateRef<any>;
@ContentChild('tableRow') tableRow!: TemplateRef<any>;
}

You might already have spotted a few code-smells. Such as the any types. Or the static string selector for the ContentChild.

1. Generics

First of all, let’s remove the any type of data. In order to do so, we can use a generic type and make sure that the type is an array of objects, by using the following code. We know, that T is an object and then the type of data is an array of this type. TypeScript is pretty smart when it comes to infering types from generics, such that we do not have to do anything in addition. Just by assigning a value to data will infer the type of T.

export class TableComponent<T extends object> {
@Input() data!: T[];
@ContentChild('tableHead') tableHead!: TemplateRef<any>;
@ContentChild('tableRow') tableRow!: TemplateRef<any>;
}

2. Directives

Another code smell is the static string …

Read the full article on ng-journal.com

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Stefan Haas

Stefan Haas

835 Followers

🅰️Angular ✍🏻Blogger 👨‍💻 Freelancer 🧙‍♂️ Trainer & Consultant. ng-journal.com