-
Notifications
You must be signed in to change notification settings - Fork 26.2k
feat(compiler): Support instanceof operator in Built-in control flow (Angular templates) #59975
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
While this is totally doable (in a similar way we implemented support for This is the primary reason we haven't implemented it yet. Also this is a variant of #43485. |
@JeanMeche |
It's the class MyComponent {
protected SomeClass = SomeClass;
} This is due to template only having access to the class properties and not the lexical scope. |
Explicitly exposing the class symbol as a class property to use it in the template is quite awful to read. I now understand the implementation challenges—since the template itself has no way of recognizing the class symbol. Would it be a risky approach to create a custom pipe in the form of a type guard function? For example, something like this: import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'isInstanceOf'
})
export class IsInstanceOfPipe implements PipeTransform {
transform(value: any, classType: any): boolean {
return value instanceof classType;
}
} Usage in the template: @if(myObject | isInstanceOf: SomeClass) {
<div>
This is an instance of SomeClass!
</div>
} Would this be a feasible alternative, or are there significant risks involved? |
The custom pipe would have the same issue, you would need to expose the class symbol. Also I'm not sure that with a pipe, type narrowing would work. |
Ooooops. You're right! Thanks for your answer! 😊 |
I would add that, AFAIK, most Angular developers prefer using plain interfaces over classes for data, and that a discriminated union type is often a good alternative to a class hierarchy and instanceof: interface RegularUser {
type: 'regular';
name: string;
}
interface AdminUser {
type: 'admin';
name: string;
permissions: Array<string>;
}
type User = RegularUser | AdminUser; @if (user.type === 'admin') {
{{ user.permissions | json }}
} |
@jnizet thx for answer! The suggestion I mentioned above arises from the specific requirements of the project I am developing, which necessitate some level of abstraction. I wanted to avoid expanding by creating separate properties, and I hope you understand this intent. I acknowledge that using instanceof in templates is highly restrictive and applicable only to very specific situations. I am also reconsidering this approach myself. However, if the argument is that "instanceof is unnecessary because most Angular developers differentiate data using plain interfaces," I believe that reasoning is somewhat unreasonable. I think Angular templates should be able to implement TypeScript or JavaScript expressions as they are, as stated in the "title" of #43485 |
Wouldn't it be possible to make the template part of the class? (and not just a separat extended class) And this would also allow using private properties in the template. |
This wouldn't fix the issue with accessing symbols that are not class members. |
sure, but you could just import |
IMO, it is still better to write isSomeClass(candidate: unknown): candidate is SomeClass {
return candidate instanceof SomeClass;
} with Shorter code, clearer intent, more like TS |
Which @angular/* package(s) are relevant/related to the feature request?
compiler
Description
I'm interested in hearing opinions on allowing the use of the instanceof operator within the @if control block. Sometimes, I want to expose a template based on the instance of an object rather than its properties.
While Angular templates is designed with a declarative UI composition in mind, I wonder if instanceof might not be considered declarative enough. If there is any reason for not considering it, could it be related to performance or debugging concerns?
Example:
Proposed solution
Here is a stackblitz
Alternatives considered
Pre-Computed Properties: Compute the instanceof result in the component and bind it to the template.
Custom Pipe: Use a custom pipe to encapsulate the instanceof logic.
Custom Structural Directive: Create a directive to handle the instanceof check declaratively.
The text was updated successfully, but these errors were encountered: