In keyword in binary expression of an HTML template
One of the new features in Angular 20.0.0-next.8 is the "in" keyword in binary expressions in templates. This keyword enables testing the existence of properties in an object before their values are interpolated in Angular expressions. Without it, the component class defines methods to perform the check and invokes them in the template. The Problem It Solves Supporting the "in" keyword in a template takes one step closer to making Angular expressions behave like TypeScript expressions. First, let's update Angular to the latest version 20. As of this writing, the Angular version is 20.0.0.next-9. ng update @angular/core @angular/cli --next In this demo, we will define Fish, Dog, and Cat interfaces that extend the Animal interface and possess distinct properties. In the AppComponent, there is an animals array typed as the union of Fish, Dog, and Cat. Since the array has polymorphic interfaces, the "in" keyword tests the existence of the properties before their values are displayed in Angular expressions, compared in the test condition of the if statement, and bound to CSS classes. Defining the Animal Type First, we define the interfaces of Animal, Dog, Cat, and Fish. export interface Animal {} export interface Fish extends Animal { swim: string; } export interface Dog extends Animal { noise: string; run: string; swim: string } export interface Cat extends Animal { noise: string; jump: string; } The Fish, Dog, Cat interfaces extend the Animal interface: Fish has a swim property only; Dog has noise, run, and swim properties, while Cat has noise and jump properties. Create Animals in AppComponent @Component({ selector: 'app-root', templateUrl: './app.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class AppComponent { animals: (Cat | Dog | Fish)[] = [ { noise: 'barks', run: 'a beach', swim: 'a swimming pool', }, { noise: 'meows', jump: 'on the sofa', }, { swim: 'an aquarium', }, ] } In the AppComponent, I initialized an animals array with instances of Cat, Dog, and Fish. Now, I demonstrated the "in" keyword in the HTML template of the AppComponent. Example 1: Use the In Keyword in the Expressions @for (animal of animals; track animal) { @let properties = ['swim', 'noise', 'run', 'jump']; @for (property of properties; track property) { {{ property in animal ? `${property} in animal` : `${property} not in animal` }} } } In this example, the for loop iterates the properties array to check the presence of the properties in the animal object. If the object has the property, the component displays "${property} in animal". Otherwise, the component displays "${property} not in animal". When the animal is a Dog, the results are: swim in animal noise in animal run in animal jump not in animal Case 2: Use the In Keyword in the new Control Flow Syntax @for (animal of animals; track animal) { @let canSwim = 'swim' in animal; @if (canSwim) { {{ `The animal swims in ${animal.swim}.` }} } @let canNoise = 'noise' in animal; @if (canNoise) { {{ `The animal ${animal.noise}.` }} } @let canRun = 'run' in animal; @if (canRun) { {{ `The animal runs in ${animal.run}.` }} } @let canJump = 'jump' in animal; @if (canJump) { {{ `The animal jumps in ${animal.jump}.` }} } } In this example, the "in" keyword in the binary expressions is evaluated, and the results are stored in the temporary variables. The if control flow tests the variables and renders the paragraph elements when the condition is true. When the animal is a Dog, the results are The animal swims in a swimming pool. The animal barks. The animal runs in a beach. Case 3: Bind the results of the In Keyword to CSS Classes .run { color: rebeccapurple; } .swim { color: goldenrod; } .jump { color: fuchsia; } .noise { color: crimson; } @for (animal of animals; track animal) { @let canSwim = 'swim' in animal; {{ `The animal swims in ${animal.swim}.` }} @let canNoise = 'noise' in animal; {{ `The animal ${animal.noise}.` }} @let canRun = 'run' in animal; {{ `The animal runs in ${animal.run}.` }} @let canJump = 'jump' in animal; {{ `The animal jumps in ${animal.jump}.` }} } In this example, the results of the "in" keyword are used to show or hide the CSS classes. If the animal object has the swim property, the swim class will be applied to the paragraph element, and the text will be rendered goldenrod. If the animal object has the noise property, the noise class will render the text crimson. If the animal object has the run property, the text color is rebeccapurple. Finally,

One of the new features in Angular 20.0.0-next.8 is the "in" keyword in binary expressions in templates. This keyword enables testing the existence of properties in an object before their values are interpolated in Angular expressions. Without it, the component class defines methods to perform the check and invokes them in the template.
The Problem It Solves
Supporting the "in" keyword in a template takes one step closer to making Angular expressions behave like TypeScript expressions.
First, let's update Angular to the latest version 20. As of this writing, the Angular version is 20.0.0.next-9.
ng update @angular/core @angular/cli --next
In this demo, we will define Fish
, Dog
, and Cat
interfaces that extend the Animal
interface and possess distinct properties. In the AppComponent
, there is an animals
array typed as the union of Fish
, Dog
, and Cat
. Since the array has polymorphic interfaces, the "in" keyword tests the existence of the properties before their values are displayed in Angular expressions, compared in the test condition of the if statement, and bound to CSS classes.
Defining the Animal Type
First, we define the interfaces of Animal, Dog, Cat, and Fish.
export interface Animal {}
export interface Fish extends Animal {
swim: string;
}
export interface Dog extends Animal {
noise: string;
run: string;
swim: string
}
export interface Cat extends Animal {
noise: string;
jump: string;
}
The Fish
, Dog
, Cat
interfaces extend the Animal
interface: Fish
has a swim
property only; Dog
has noise
, run
, and swim
properties, while Cat
has noise
and jump
properties.
Create Animals in AppComponent
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
animals: (Cat | Dog | Fish)[] = [
{
noise: 'barks',
run: 'a beach',
swim: 'a swimming pool',
},
{
noise: 'meows',
jump: 'on the sofa',
},
{
swim: 'an aquarium',
},
]
}
In the AppComponent
, I initialized an animals
array with instances of Cat
, Dog
, and Fish
.
Now, I demonstrated the "in" keyword in the HTML template of the AppComponent
.
Example 1: Use the In Keyword in the Expressions
@for (animal of animals; track animal) {
@let properties = ['swim', 'noise', 'run', 'jump'];
@for (property of properties; track property) {
{{ property in animal ? `${property} in animal` : `${property} not in animal` }}
}
}
In this example, the for loop iterates the properties array to check the presence of the properties in the animal object. If the object has the property, the component displays "${property} in animal"
. Otherwise, the component displays "${property} not in animal"
.
When the animal is a Dog, the results are:
- swim in animal
- noise in animal
- run in animal
- jump not in animal
Case 2: Use the In Keyword in the new Control Flow Syntax
@for (animal of animals; track animal) {
@let canSwim = 'swim' in animal;
@if (canSwim) {
{{ `The animal swims in ${animal.swim}.` }}
}
@let canNoise = 'noise' in animal;
@if (canNoise) {
{{ `The animal ${animal.noise}.` }}
}
@let canRun = 'run' in animal;
@if (canRun) {
{{ `The animal runs in ${animal.run}.` }}
}
@let canJump = 'jump' in animal;
@if (canJump) {
{{ `The animal jumps in ${animal.jump}.` }}
}
}
In this example, the "in" keyword in the binary expressions is evaluated, and the results are stored in the temporary variables. The if control flow tests the variables and renders the paragraph elements when the condition is true.
When the animal is a Dog, the results are
- The animal swims in a swimming pool.
- The animal barks.
- The animal runs in a beach.
Case 3: Bind the results of the In Keyword to CSS Classes
.run {
color: rebeccapurple;
}
.swim {
color: goldenrod;
}
.jump {
color: fuchsia;
}
.noise {
color: crimson;
}
@for (animal of animals; track animal) {
@let canSwim = 'swim' in animal;
[class.swim]="canSwim">{{ `The animal swims in ${animal.swim}.` }}
@let canNoise = 'noise' in animal;
[class.noise]="canNoise">{{ `The animal ${animal.noise}.` }}
@let canRun = 'run' in animal;
[class.run]="canRun">{{ `The animal runs in ${animal.run}.` }}
@let canJump = 'jump' in animal;
[class.jump]="canJump">{{ `The animal jumps in ${animal.jump}.` }}
}
In this example, the results of the "in" keyword are used to show or hide the CSS classes. If the animal
object has the swim
property, the swim
class will be applied to the paragraph element, and the text will be rendered goldenrod. If the animal
object has the noise
property, the noise
class will render the text crimson. If the animal
object has the run
property, the text color is rebeccapurple. Finally, if the animal
object has the jump
property, the paragraph element has the jump
class and fuchsia text color.
When the animal is a Dog, we will see
- The animal swims in a swimming pool in goldenrod.
- The animal barks in crimson, and
- The animal runs on a beach in rebeccapurple.
Benefits
Supporting the in keyword in the template offers several advantages:
- The template can check the presence of properties in an object.
- The Angular expression will someday become a plain TypeScript expression.
- The "in" keyword is evaluated to a boolean and can be displayed in expressions, enabled CSS classes, and tested in the new control flow.
Conclusion
Angular expressions are making strides toward being like plain TypeScript expressions. In Angular 19 and 20, templates can perform template strings, tagged template literals, exponential operators, and the "in" keyword in binary expressions.