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

fix(common): infer correct type when trackBy is used in ngFor #41995

Closed
wants to merge 3 commits into from

Conversation

JoostK
Copy link
Member

@JoostK JoostK commented May 7, 2021

See individual commits

Fixes #40125

@JoostK JoostK added target: patch This PR is targeted for the next patch release area: compiler Issues related to `ngc`, Angular's template compiler P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent compiler: template type-checking labels May 7, 2021
@ngbot ngbot bot modified the milestone: Backlog May 7, 2021
@google-cla google-cla bot added the cla: yes label May 7, 2021
@JoostK JoostK added the area: common Issues related to APIs in the @angular/common package label May 7, 2021
@JoostK JoostK changed the title Type checking track by fix(common): infer correct type when trackBy is used in ngFor May 7, 2021
@JoostK JoostK marked this pull request as ready for review May 7, 2021 21:53
@pullapprove pullapprove bot requested a review from jessicajaniuk May 7, 2021 21:53
@JoostK JoostK added the action: review The PR is still awaiting reviews from at least one requested reviewer label May 7, 2021
Copy link
Contributor

@jessicajaniuk jessicajaniuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🍪

reviewed-for: public-api

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Reviewed-for: public-api

@@ -121,7 +121,7 @@ export interface IterableChangeRecord<V> {
* @publicApi
*/
export interface TrackByFunction<T> {
(index: number, item: T): any;
<U extends T>(index: number, item: U): any;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment here that adds context to <U extends T> with a link to the issue?

@pullapprove pullapprove bot requested a review from jessicajaniuk May 10, 2021 22:50
Copy link
Member

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-for: public-api

Copy link
Member

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-for: public-api

@pullapprove pullapprove bot requested a review from atscott May 11, 2021 14:02
Copy link
Contributor

@jessicajaniuk jessicajaniuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🍪

reviewed-for: public-api

@AndrewKushnir AndrewKushnir added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed state: blocked labels Jun 2, 2021
The ngtsc test targets have fake declarations files for `@angular/core`
and `@angular/common` and the template type checking tests can leverage
the fake common declarations instead of declaring its own types.
…e_core`

The `TrackByFunction` is declared in `@angular/core` so it should also be
included in `fake_core` instead of `fake_common`.
When a `trackBy` function is used that accepts a supertype of the iterated
array's type, the loop variable would undesirably be inferred as the supertype
instead of the array's item type. This commit adds an inferred type parameter
to `TrackByFunction` to allow an extra degree of freedom, enabling the
loop value to be inferred as the most narrow type.

Fixes angular#40125
@JoostK JoostK removed the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Jun 2, 2021
@JoostK
Copy link
Member Author

JoostK commented Jun 2, 2021

@AndrewKushnir This one is ready for another round of presubmit.

@AndrewKushnir
Copy link
Contributor

Global Presubmit #2.

@AndrewKushnir AndrewKushnir removed the action: presubmit The PR is in need of a google3 presubmit label Jun 3, 2021
@AndrewKushnir
Copy link
Contributor

@JoostK presubmits (including a global one) went well and this PR looks ready for merge (just needs the "merge" label).

@JoostK JoostK added the action: merge The PR is ready for merge by the caretaker label Jun 3, 2021
jessicajaniuk pushed a commit that referenced this pull request Jun 3, 2021
…e_core` (#41995)

The `TrackByFunction` is declared in `@angular/core` so it should also be
included in `fake_core` instead of `fake_common`.

PR Close #41995
jessicajaniuk pushed a commit that referenced this pull request Jun 3, 2021
…1995)

When a `trackBy` function is used that accepts a supertype of the iterated
array's type, the loop variable would undesirably be inferred as the supertype
instead of the array's item type. This commit adds an inferred type parameter
to `TrackByFunction` to allow an extra degree of freedom, enabling the
loop value to be inferred as the most narrow type.

Fixes #40125

PR Close #41995
jessicajaniuk pushed a commit that referenced this pull request Jun 3, 2021
The ngtsc test targets have fake declarations files for `@angular/core`
and `@angular/common` and the template type checking tests can leverage
the fake common declarations instead of declaring its own types.

PR Close #41995
jessicajaniuk pushed a commit that referenced this pull request Jun 3, 2021
…e_core` (#41995)

The `TrackByFunction` is declared in `@angular/core` so it should also be
included in `fake_core` instead of `fake_common`.

PR Close #41995
jessicajaniuk pushed a commit that referenced this pull request Jun 3, 2021
…1995)

When a `trackBy` function is used that accepts a supertype of the iterated
array's type, the loop variable would undesirably be inferred as the supertype
instead of the array's item type. This commit adds an inferred type parameter
to `TrackByFunction` to allow an extra degree of freedom, enabling the
loop value to be inferred as the most narrow type.

Fixes #40125

PR Close #41995
AleksanderBodurri added a commit to rangle/angular-devtools that referenced this pull request Jun 21, 2021
…ByFunction

Previously `DefaultIterableDiffer` was able to infer the type of it's generic by reading the type contract defined by the user defined trackBy function. This was because `TrackByFunction` can be specified with a generic that is used to type its second argument. If this generic is not provided, like in this case, typescript infers this type from the function contract directly. In this case this inferred type was `FlatNode`. This inference is then propagated to `DefaultIterableDiffer`, which is why we were not seeing this error previously.

A change in the framework made it so the second argument of `TrackByFunction` is typed as a generic that extends the generic passed into `TrackByFunction`. Since we had not previously passed in this generic to `TrackByFunction`, this type was inferred as an extension of `unknown`, causing a type error when passed as an argument to the `DefaultIterableDiffer` constructor.

Now the functions being used are typed directly as `TrackByFunction<FlatNode>`

For clarity, the `DefaultIterableDiffer` generic is now also typed as `FlatNode`.

See angular/angular#41995 for the framework change.
mgechev pushed a commit to rangle/angular-devtools that referenced this pull request Jun 22, 2021
…ByFunction (#862)

Previously `DefaultIterableDiffer` was able to infer the type of it's generic by reading the type contract defined by the user defined trackBy function. This was because `TrackByFunction` can be specified with a generic that is used to type its second argument. If this generic is not provided, like in this case, typescript infers this type from the function contract directly. In this case this inferred type was `FlatNode`. This inference is then propagated to `DefaultIterableDiffer`, which is why we were not seeing this error previously.

A change in the framework made it so the second argument of `TrackByFunction` is typed as a generic that extends the generic passed into `TrackByFunction`. Since we had not previously passed in this generic to `TrackByFunction`, this type was inferred as an extension of `unknown`, causing a type error when passed as an argument to the `DefaultIterableDiffer` constructor.

Now the functions being used are typed directly as `TrackByFunction<FlatNode>`

For clarity, the `DefaultIterableDiffer` generic is now also typed as `FlatNode`.

See angular/angular#41995 for the framework change.
JoostK added a commit to JoostK/angular that referenced this pull request Jun 28, 2021
…rackBy` function

In angular#41995 the type of `TrackByFunction` was changed such that the
declaration of a `trackBy` function did not cause the item type to be
widened to the `trackBy`'s item type, which may be a supertype of the
iterated type. This has introduced situations where the template type
checker is now reporting errors for cases where a `trackBy` function is
no longer assignable to `TrackByFunction`.

This commit fixes the error by also including the item type `T` in
addition to the constrained type parameter `U`, allowing TypeScript to
infer an appropriate `T`.

Fixes angular#42609
JoostK added a commit to JoostK/angular that referenced this pull request Jul 3, 2021
…rackBy` function

In angular#41995 the type of `TrackByFunction` was changed such that the
declaration of a `trackBy` function did not cause the item type to be
widened to the `trackBy`'s item type, which may be a supertype of the
iterated type. This has introduced situations where the template type
checker is now reporting errors for cases where a `trackBy` function is
no longer assignable to `TrackByFunction`.

This commit fixes the error by also including the item type `T` in
addition to the constrained type parameter `U`, allowing TypeScript to
infer an appropriate `T`.

Fixes angular#42609
@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 Jul 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: common Issues related to APIs in the @angular/common package area: compiler Issues related to `ngc`, Angular's template compiler cla: yes compiler: template type-checking P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

trackBy incorrectly changes item type
6 participants