Enhancing template type checking for your custom directives
In this recipe, you'll learn how to improve type checking in templates for your custom Angular directives using the static template guards that the recent versions of Angular have introduced. We'll enhance the template type checking for our appHighlight
directive so that it only accepts a narrowed set of inputs.
Getting ready
The project we are going to work with resides in chapter02/start_here/enhanced-template-type-checking
, inside the cloned repository:
- Open the project in VS Code.
- Open the terminal, and run
npm install
to install the dependencies of the project. - Once done, run
ng serve -o
.This should open the app in a new browser tab, and you should see something like this:
Now that we have the app running, let's see the steps for this recipe in the next section.
How to do it…
- First off, we'll try to identify the problem, and that boils down to the ability to pass any string as a color to the
highlightColor
attribute/input for theappHighlight
directive. Give it a try. Provide the'#dcdcdc'
value as the input and you'll have a broken highlight color, but no errors whatsoever:... <div class="content" role="main"> ... <p class="text-content" appHighlight [highlightColor]="'#dcdcdc'" [highlightText]="searchText"> ... </p> </div>
- Well, how do we fix it? By adding some
angularCompileOptions
to ourtsconfig.json
file. We'll do this by adding a flag namedstrictInputTypes
astrue
. Stop the app server, modify the code as follows, and rerun theng serve
command to see the changes:{ "compileOnSave": false, "compilerOptions": { ... }, "angularCompilerOptions": { "strictInputTypes": true } }
You should see something like this:
- Well, great! Angular now identifies that the provided
'#dcdcdc'
value is not assignable to theHighlightColor
type. But what happens if someone tries to providenull
as the value? Would it still be fine? The answer is no. We would still have a broken experience, but no error whatsoever. To fix this, we'll enable two flags for ourangularCompilerOptions
—strictNullChecks
andstrictNullInputTypes
:{ "compileOnSave": false, "compilerOptions": { ... }, "angularCompilerOptions": { "strictInputTypes": true, "strictNullChecks": true, "strictNullInputTypes": true } }
- Update the
app.component.html
file to providenull
as the value for the[highlightColor]
attribute, as follows:... <div class="content" role="main"> ... <p class="text-content" appHighlight [highlightColor]="null" [highlightText]="searchText"> ... </div>
- Stop the server, save the file, and rerun
ng serve
, and you'll see that we now have another error, as shown here: - Now, instead of so many flags for even further cases, we can actually just put two flags that do all the magic for us and cover most of our applications—the
strictNullChecks
flag and thestrictTemplates
flag:{ "compileOnSave": false, "compilerOptions": { ... }, "angularCompilerOptions": { "strictNullChecks": true, "strictTemplates": true } }
- Finally, we can import the
HighlightColor
enum into ourapp.component.ts
file. We will add ahColor
property to theAppComponent
class and will assign it a value from theHighlightColor
enum, as follows:import { Component } from '@angular/core'; import { HighlightColor } from './directives/highlight.directive'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { searchText = ''; hColor: HighlightColor = HighlightColor.LightCoral; }
- We'll now use the
hColor
property in theapp.component.html
file to pass it to theappHighlight
directive. This should fix all the issues and make light coral the assigned highlight color for our directive:<div class="content" role="main"> ... <p class="text-content" appHighlight [highlightColor]="hColor" [highlightText]="searchText"> ... </p> </div>
See also
- Angular structural directives documentation (https://angular.io/guide/structural-directives)
- Template type checking in Angular documentation (https://angular.io/guide/template-typecheck#template-type-checking)
- Troubleshooting template errors in Angular documentation (https://angular.io/guide/template-typecheck#troubleshooting-template-errors)