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
Conversation
trackBy
is used in ngFor
244caaa
to
818fc8e
Compare
There was a problem hiding this 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
There was a problem hiding this 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; |
There was a problem hiding this comment.
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?
There was a problem hiding this 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
There was a problem hiding this 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
There was a problem hiding this 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
43cfc55
to
aa60c0b
Compare
aa60c0b
to
f8d277f
Compare
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
f8d277f
to
c298698
Compare
@AndrewKushnir This one is ready for another round of presubmit. |
@JoostK presubmits (including a global one) went well and this PR looks ready for merge (just needs the "merge" label). |
…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
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
…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
…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.
…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.
…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
…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
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
See individual commits
Fixes #40125