Skip to content
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

Variables created in the template always have type any #1155

Closed
BlindDespair opened this issue Feb 26, 2021 · 6 comments
Closed

Variables created in the template always have type any #1155

BlindDespair opened this issue Feb 26, 2021 · 6 comments
Labels
discussion ivy Feature / enhancement / bug fix in Ivy user XP Issue related to user experience

Comments

@BlindDespair
Copy link

BlindDespair commented Feb 26, 2021

Describe the bug
With the latest version of angular language service we lost the type safety in the template when using techniques that create new variables, e.g. when using *ngFor or *ngIf="something as some".
I experienced this in all my projects while working from different machines. Here is an example:
image
You can clearly see that documentTypes is typed here, however documentType becomes type any:
image
This same issue can be seen also with *ngIf when using as, I am not sure if anything else is affected.

To Reproduce

Steps to reproduce the behavior:

  1. Create any component
  2. Create a dummy list and type it with something it contains
  3. Create *ngFor in the template

Expected behavior
It should have the correct types.

Logs

[Info  - 4:18:23 PM] Angular language server process ID: 95617
[Info  - 4:18:23 PM] Using typescript/lib/tsserverlibrary v4.1.5 from .vscode/extensions/angular.ng-template-11.2.3/node_modules/typescript/lib/tsserverlibrary.js
[Info  - 4:18:23 PM] Using @angular/language-service/bundles/ivy v11.2.2 from .vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js
[Info  - 4:18:23 PM] Log file: Library/Application Support/Code/logs/20210222T081547/exthost2/Angular.ng-template/nglangsvc.log
[Info  - 4:18:26 PM] Disabling language service for /frontend/tsconfig.json because it is not an Angular project ('@angular/core/core.d.ts' could not be found). If you believe you are seeing this message in error, please reinstall the packages in your package.json.
[Info  - 4:18:58 PM] Enabling Ivy language service for /frontend/tsconfig.fix.json.
[Info  - 4:19:06 PM] Enabling Ivy language service for /frontend/tsconfig.spec.json.
[Info  - 4:19:06 PM] Enabling Ivy language service for /frontend/tsconfig.app.json.
.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:25584
                    throw err;
                    ^

Error: Duplicate decorated properties found on class 'SignDocumentTabComponent': selectedDocument
    at generateSetClassMetadataCall (.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:28012:19)
    at ComponentDecoratorHandler.analyze (.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:28909:35)
    at TraitCompiler.analyzeTrait (.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:25576:40)
    at analyze (.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:25542:44)
    at TraitCompiler.analyzeClass (.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:25564:21)
    at visit (.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:25390:26)
    at visitNodes (.vscode/extensions/angular.ng-template-11.2.3/node_modules/typescript/lib/tsserverlibrary.js:27858:30)
    at Object.forEachChild (.vscode/extensions/angular.ng-template-11.2.3/node_modules/typescript/lib/tsserverlibrary.js:28097:24)
    at visit (.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:25392:22)
    at TraitCompiler.analyze (.vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js:25394:13)
[Info  - 4:54:56 PM] Connection to server got closed. Server will restart.
[Info  - 4:54:57 PM] Angular language server process ID: 96725
[Info  - 4:54:57 PM] Using typescript/lib/tsserverlibrary v4.1.5 from .vscode/extensions/angular.ng-template-11.2.3/node_modules/typescript/lib/tsserverlibrary.js
[Info  - 4:54:57 PM] Using @angular/language-service/bundles/ivy v11.2.2 from .vscode/extensions/angular.ng-template-11.2.3/node_modules/@angular/language-service/bundles/ivy.js
[Info  - 4:54:57 PM] Log file: Library/Application Support/Code/logs/20210222T081547/exthost2/Angular.ng-template/nglangsvc.log
[Info  - 4:54:57 PM] Disabling language service for /frontend/tsconfig.json because it is not an Angular project ('@angular/core/core.d.ts' could not be found). If you believe you are seeing this message in error, please reinstall the packages in your package.json.
[Info  - 4:55:11 PM] Enabling Ivy language service for /frontend/tsconfig.fix.json.
[Info  - 4:55:16 PM] Enabling Ivy language service for /frontend/tsconfig.spec.json.
[Info  - 4:55:16 PM] Enabling Ivy language service for /frontend/tsconfig.app.json.
@anurag-roy
Copy link

I found a workaround.

Try disabling Angular: Experimental-ivy in the extension settings. It doesn't show the type on hover but at least autocomplete works.

@atscott
Copy link
Collaborator

atscott commented Mar 1, 2021

The types shown by Angular Language Service reflect what you've configured the compiler to interpret. Have you turned on strictTemplates or fullTemplateTypeCheck at the very least in the angular compiler options? If not, Angular does not type check the bodies of templates.

@Jin-K
Copy link

Jin-K commented Mar 1, 2021

this is the content of our tsconfig.json, and we have the issue since a couple of days:

{
  "compileOnSave": false,
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": ["node_modules/@types"],
    "paths": {
      "lodash/*": ["node_modules/@types/lodash-es/*"]
    },
    "lib": ["es2018", "dom"]
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}

@atscott
Copy link
Collaborator

atscott commented Mar 1, 2021

Ah, I see what's happening. fullTemplateTypeCheck is not enough to apply the template context guards: https://github.com/angular/angular/blob/e12d9dec64bc3d02e58f8f85a65a939394fb9531/packages/compiler-cli/src/ngtsc/core/src/compiler.ts#L667
If your project isn't quite ready to turn on strictTemplates, the next step to get this working is to add "strictInputTypes": true: https://github.com/angular/angular/blob/e12d9dec64bc3d02e58f8f85a65a939394fb9531/packages/compiler-cli/src/ngtsc/core/src/compiler.ts#L724

@atscott atscott added ivy Feature / enhancement / bug fix in Ivy user XP Issue related to user experience labels Mar 1, 2021
@atscott
Copy link
Collaborator

atscott commented Mar 1, 2021

Just a heads up, we're planning to add an informational diagnostic that would show up on structural directives when the compiler options are preventing the guard from being applied.

Edit: tracking issue in the angular/angular repo angular/angular#41042

alxhub added a commit to alxhub/angular that referenced this issue Mar 3, 2021
The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a warning diagnostic which
is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes angular#41042
alxhub added a commit to alxhub/angular that referenced this issue Mar 4, 2021
The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a warning diagnostic which
is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes angular#41042
alxhub added a commit to alxhub/angular that referenced this issue Mar 8, 2021
The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a warning diagnostic which
is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes angular#41042
alxhub added a commit to alxhub/angular that referenced this issue Mar 8, 2021
The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a suggestion diagnostic
which is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes angular#41042
alxhub added a commit to alxhub/angular that referenced this issue Mar 17, 2021
The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a suggestion diagnostic
which is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes angular#41042
alxhub added a commit to alxhub/angular that referenced this issue Mar 19, 2021
The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a suggestion diagnostic
which is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes angular#41042
josephperrott pushed a commit to angular/angular that referenced this issue Mar 23, 2021
…mal (#41072)

The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a suggestion diagnostic
which is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes #41042

PR Close #41072
TeriGlover pushed a commit to TeriGlover/angular that referenced this issue Apr 5, 2021
…mal (angular#41072)

The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.

If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.

This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.

To address this confusion, this commit implements a suggestion diagnostic
which is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.

Fixes angular/vscode-ng-language-service#1155
Closes angular#41042

PR Close angular#41072
@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Apr 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
discussion ivy Feature / enhancement / bug fix in Ivy user XP Issue related to user experience
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants