The $any() Type Cast Function In Angular

I recently came across a project that had a certain function littered throughout the codebase. It was in many HTML templates and looked something like :

{{$any(myVariable).property}}

At first, the use of the dollar sign $ threw me off (Is someone introducing jQuery here?!). But infact, it’s a special operator used in very rare cases within Angular templates. It can actually take a while to come across a scenario that requires it’s use, but when you do, it’s a life saver.

The first thing to note is that everything about this resolves around Angular AOT compilation. You can read more about it here : https://angular.io/guide/aot-compiler

But in short, most angular projects will be set to have AOT turned on, but only for production. This generally means that if you run “ng build”, you will not use AOT, but if you run “ng build –production”, you will. To be absolutely sure, open your angular.json and hit Ctrl + F for instances of “aot”, and check which configuration they are set under. If in doubt, and you just want to test things out, you can also run “ng build –aot” to force AOT on anyway.

With that out of the way, what does AOT actually do? Well it compiles your application ahead of time. And as part of that, it can (or by default, will) do a strict type checking process. That is, it will ensure that all types used within your application are used correctly (Numbers are treated as numbers, strings are treated as strings etc).

On this project, I noticed that if I built the application using AOT, I got an error similar to :

ERROR in src/app/app.component.html(1,3): Property 'firstName' does not exist on type '{}'.

And again, I did not get this error without AOT turned on.

To recreate the issue, I was using a component that looked something like :

export class AppComponent implements OnInit {
  myPerson = {}; 
  constructor() {
  }
  ngOnInit(): void {
    (this.myPerson as any).firstName = 'Wade';
  }
}

Notice how the myPerson variable is initialized as an empty object (Something that someone writing in vanilla javascript may do). In Angular, I can cast this object to an “any” type to set properties in my component. But what about in the HTML?

I had something like :

{{myPerson.firstName}}

Which seemed fine to me! But AOT uses strict typing and wants to ensure that the myPerson object actually will have a firstName property. Unfortunately in this case it can’t.

And that’s where the $any() function comes in.

{{$any(myPerson).firstName}}

This now converts the myPerson object to an “any” type, and allows it to act as such even in HTML. It’s basically identical to the cast we do in the backend of our component.

The main thing you’ll be asking yourself is, but when will I do something like :

myPerson = {}; 

In my case, I didn’t! But I was using a library that was initially build for vanilla javascript and exposed objects as such. And for that, the $any() function was a life saver!

Leave a Reply

Your email address will not be published.