Repository navigation
Closed
Labels
area: language-serviceIssues related to Angular's VS Code language serviceIssues related to Angular's VS Code language servicetype: bug/fix
Description
I'm submitting a ...
[ ] Regression (behavior that used to work and stopped working in a new release)
[] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
When I have a variable in my component with a union type, the language service will complain if I reference any properties which are not common to all members of the union type. Sometimes it may be valid to try to reference these non-shared properties, e.g.:
import { Component } from '@angular/core';
export interface Line {
length: number;
dimensions: number;
}
export interface Plane {
area: number;
dimensions: number;
}
@Component({
selector: 'app-root',
template: ` {{ shape.length || shape.area }}
{{ shape.dimensions }}
<div *ngFor="let item of collection">
{{ item.length || item.area }}
{{ item.dimensions }}
</div>
`})
export class AppComponent {
collection: Array<Line|Plane> = [];
shape: Line|Plane;
}Here is a screenshot of the output from VS Code using the language service plugin:
Expected behavior
I would expect to be able to use the above construction without errors.
Minimal reproduction of the problem with instructions
- Create a new angular CLI project with
@angular/cli 1.2.0 - Replace the contents of app.component.ts with the code above
- View in VS Code with the language service plugin enabled. My version of the plugin uses
@angular/language-service@4.1.0-beta
What is the motivation / use case for changing the behavior?
The example above illustrates a simple uses case. In my app I have a situation where I have a generic component which can be passed different types of object, and uses the || operator to display the first truthy value.
Please tell us about your environment
For Tooling issues:
- Node version: 7.7.1
- Platform: Windows 10
- VS Code 1.13.1
- @angular/language-service@4.1.0-beta
- Typescript@2.1.5
Reacted by Lee Goddard, Lana-sloth, Ondrazar, Ezequiel Lerman, Lucas Klaassen, Andreas Bjerga, Wayne Maurer, Pavel Gurecki and Jon Wallsten
Metadata
Metadata
Assignees
Labels
area: language-serviceIssues related to Angular's VS Code language serviceIssues related to Angular's VS Code language servicetype: bug/fix
Activity
chuckjaz commentedon Jul 7, 2017
This is equivalent to this playground example in which TypeScript also reports an error.
As we improve type checking during AOT compilation this will be reported as an error in 5.0 as well as we will use TypeScript's type checker instead of our own.
michaelbromley commentedon Jul 9, 2017
Thanks for the reply. The difference is that in regular TS code I can cast before accessing the property, which I cannot do in the template.
I guess the way to do this now would be then to provide a method on the component which performs the cast and returns the appropriate value, and then just call this method in the template.
chuckjaz commentedon Jul 10, 2017
That is certainly what we recommend. The templates expressions should be simple and any complicated logic should be in the component.
albv commentedon Dec 4, 2017
@chuckjaz and what about tagged union types? For example:
Should we do type casting in component also? Like this:
chuckjaz commentedon Dec 4, 2017
Interesting problem. For this to work I need some way to declare the type relation between
NgSwitch.ngSwitchandNgSwitchCase.ngSwitchCase. For this I would need to add a type parameters toNgSwitchandNgSwitchCasesuch that it would look like:Following the pattern of #20702, I would then need to declare a guard for
ngSwitchwhich is a bit odd since it the guard would need to be declared inNgSwitchCase, but, ignoring that for a bit, the guard might look something like,which would then allow me to generate the following type-check block:
A simplified version of this can be seen in the playground here.
I currently can only get this to work for the string union types and deciding when and how to apply it is a bit tricky in general (the odd part ignored above) but this seems like we might eventually be able to do this.
Unfortunately, adding a type parameter to
NgSwitchis a breaking change that will not be able to land until 6 but I probably would not get to this before 6 anyway so that is not blocker.chuckjaz commentedon Dec 4, 2017
I added #20780 to track this.
albv commentedon Dec 5, 2017
Looking forward to see it landed. Thanks for the detailed response @chuckjaz
crutchcorn commentedon May 1, 2018
This does not seem to be fixed still. Type unions are still not working as expected in templates
istvandesign commentedon Oct 3, 2018
error: number | ErrorType = <ErrorType>{};will cause template errors in vscode with Angular 6. Also vscode seems to be much slower for some reason with the template open.simeyla commentedon Dec 11, 2018
@albv Your code looks so freakishly like mine I actually thought it was mine for a second.
That is to say I'm working on a similar problem with a list of shopping cart payment methods.
I modified your answer slightly, to what I think makes a little more sense if you don't want to change the object being 'switched' upon. In your case you added
paymentMethodAsPayPal()to the class (component) that containspaymentMethod.In my case, I have an array of pure (from JSON) data representing a list of payment methods, and couldn't / didn't want to add methods onto it. Instead I created the following method to use in the component:
Component class
Component template
This ends up looking more like a 'cast' within a block where you've clearly established the data type.
If you really think people can make a mistake you could do a check inside
asCreditCardto make sure it really was the correct typeangular-automatic-lock-bot commentedon Sep 14, 2019
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.