-
Notifications
You must be signed in to change notification settings - Fork 26.2k
feat(common): stricter types for SlicePipe #30156
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
Conversation
1ff3059
to
a52ffb9
Compare
@@ -28,14 +28,17 @@ import {expect} from '@angular/platform-browser/testing/src/matchers'; | |||
it('should support lists', () => { expect(() => pipe.transform(list, 0)).not.toThrow(); }); | |||
|
|||
it('should not support other objects', | |||
() => { expect(() => pipe.transform({}, 0)).toThrow(); }); | |||
() => { expect(() => pipe.transform({} as string, 0)).toThrow(); }); |
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.
as any
would be less weird
06dbaa7
to
07fc080
Compare
@@ -62,6 +62,10 @@ export class SlicePipe implements PipeTransform { | |||
* - **if positive**: return all items before `end` index of the list or string. | |||
* - **if negative**: return all items before `end` index from the end of the list or string. | |||
*/ | |||
transform<T>(value: T[], start: number, end?: number): T[]; |
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.
I guess it should also accept ReadonlyArray<T>
?
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.
Good point. I don't know if it's best to have another overload, or if transform<T, A extends ReadonlyArray<T>>(value: A, start: number, end?: number): A;
is enough...
07fc080
to
cfeb59d
Compare
if this PR presubmits without any failures in google3 which would confirm the theory that this is not a de facto breaking change then I'd be fine merging this change into the 8.0.x branch. |
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. Running presubmit...
@IgorMinar Looks like this passed TAP in google. Are you good with merging this? |
@@ -62,6 +62,10 @@ export class SlicePipe implements PipeTransform { | |||
* - **if positive**: return all items before `end` index of the list or string. | |||
* - **if negative**: return all items before `end` index from the end of the list or string. | |||
*/ | |||
transform<T, A extends ReadonlyArray<T>>(value: A, start: number, end?: number): A; |
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.
I don't think this is technically correct. ReadonlyArray<T>.slice()
returns a T[]
not a ReadonlyArray<T>
. SlicePipe
should do the same - slicing a ReadonlyArray<T>
results in a T[]
.
That is, it should be valid in a template to write:
{{ foo(readOnly | slice:0:3) }}
Even if foo()
requires an argument of T[]
and readOnly
is a ReadonlyArray<T>
.
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.
Maybe it could treat Array<T>
and ReadonlyArray<T>
as two overloads.
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.
There's no real need - since slice
makes a copy, it's okay to accept ReadonlyArray
(a strictly narrower type than Array
) and always return the mutable Array
.
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.
@alxhub I updated the signature to accept ReadonlyArray<T>
and return Array<T>
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.
Ok. Lgtm
cfeb59d
to
15032f9
Compare
Adds overloads to the `transform` methods of `SlicePipe`, to have better types than `any` for `value` and `any` as a return. With this commit, using `slice` in an `ngFor` still allow to type-check the content of the `ngFor` with `fullTemplateTypeCheck` enabled in Ivy: <div *ngFor="let user of users | slice:0:2">{{ user.typo }}</div> | `typo` does not exist on type `UserModel` whereas it is currently not catched (as the return of `slice` is `any`) neither in VE nor in Ivy. BREAKING CHANGE `SlicePipe` now only accepts an array of values, a string, null or undefined. This was already the case in practice, and it still throws at runtime if another type is given. But it is now a compilation error to try to call it with an unsupported type.
15032f9
to
3fcdd14
Compare
Adds overloads to the `transform` methods of `SlicePipe`, to have better types than `any` for `value` and `any` as a return. With this commit, using `slice` in an `ngFor` still allow to type-check the content of the `ngFor` with `fullTemplateTypeCheck` enabled in Ivy: <div *ngFor="let user of users | slice:0:2">{{ user.typo }}</div> | `typo` does not exist on type `UserModel` whereas it is currently not catched (as the return of `slice` is `any`) neither in VE nor in Ivy. BREAKING CHANGE `SlicePipe` now only accepts an array of values, a string, null or undefined. This was already the case in practice, and it still throws at runtime if another type is given. But it is now a compilation error to try to call it with an unsupported type. PR Close #30156
Adds overloads to the `transform` methods of `SlicePipe`, to have better types than `any` for `value` and `any` as a return. With this commit, using `slice` in an `ngFor` still allow to type-check the content of the `ngFor` with `fullTemplateTypeCheck` enabled in Ivy: <div *ngFor="let user of users | slice:0:2">{{ user.typo }}</div> | `typo` does not exist on type `UserModel` whereas it is currently not catched (as the return of `slice` is `any`) neither in VE nor in Ivy. BREAKING CHANGE `SlicePipe` now only accepts an array of values, a string, null or undefined. This was already the case in practice, and it still throws at runtime if another type is given. But it is now a compilation error to try to call it with an unsupported type. PR Close angular#30156
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. |
Adds overloads to the
transform
methods ofSlicePipe
,to have better types than
any
forvalue
andany
as a return.With this commit, using
slice
in anngFor
still allow to type-check the content of thengFor
with
fullTemplateTypeCheck
enabled in Ivy:whereas it is currently not catched (as the return of
slice
isany
) neither in VE nor in Ivy.BREAKING CHANGE
SlicePipe
now only accepts an array of values, a string, null or undefined.This was already the case in practice, and it still throws at runtime if another type is given.
But it is now a compilation error to try to call it with an unsupported type.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: #30086
What is the new behavior?
The
slice
pipe is now properly typed, so Ivy andfullTemplateTypeCheck
enabled will catch errors inside anngFor
using a slice.Does this PR introduce a breaking change?
Technically this changes the API, as it was previously possible to (wrongly) call
slice.transform(14, 1);
which still throws at runtime but is now a compile time error.Other information
@alxhub as we talked about it on Slack