Skip to content

Commit 722b2fa

Browse files
cexbrayatjasonaden
authored andcommittedMay 17, 2019
feat(common): stricter types for SlicePipe (#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 #30156
1 parent 124d1ab commit 722b2fa

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed
 

‎packages/common/src/pipes/slice_pipe.ts

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export class SlicePipe implements PipeTransform {
6262
* - **if positive**: return all items before `end` index of the list or string.
6363
* - **if negative**: return all items before `end` index from the end of the list or string.
6464
*/
65+
transform<T>(value: ReadonlyArray<T>, start: number, end?: number): Array<T>;
66+
transform(value: string, start: number, end?: number): string;
67+
transform(value: null, start: number, end?: number): null;
68+
transform(value: undefined, start: number, end?: number): undefined;
6569
transform(value: any, start: number, end?: number): any {
6670
if (value == null) return value;
6771

‎packages/common/test/pipes/slice_pipe_spec.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,23 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
2626
describe('supports', () => {
2727
it('should support strings', () => { expect(() => pipe.transform(str, 0)).not.toThrow(); });
2828
it('should support lists', () => { expect(() => pipe.transform(list, 0)).not.toThrow(); });
29+
it('should support readonly lists',
30+
() => { expect(() => pipe.transform(list as ReadonlyArray<number>, 0)).not.toThrow(); });
2931

3032
it('should not support other objects',
31-
() => { expect(() => pipe.transform({}, 0)).toThrow(); });
33+
// this would not compile
34+
// so we cast as `any` to check that it throws for unsupported objects
35+
() => { expect(() => pipe.transform({} as any, 0)).toThrow(); });
3236
});
3337

3438
describe('transform', () => {
3539

3640
it('should return null if the value is null',
3741
() => { expect(pipe.transform(null, 1)).toBe(null); });
3842

43+
it('should return undefined if the value is undefined',
44+
() => { expect(pipe.transform(undefined, 1)).toBe(undefined); });
45+
3946
it('should return all items after START index when START is positive and END is omitted',
4047
() => {
4148
expect(pipe.transform(list, 3)).toEqual([4, 5]);

‎tools/public_api_guard/common/common.d.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,10 @@ export interface PopStateEvent {
410410
export declare function registerLocaleData(data: any, localeId?: string | any, extraData?: any): void;
411411

412412
export declare class SlicePipe implements PipeTransform {
413-
transform(value: any, start: number, end?: number): any;
413+
transform<T>(value: ReadonlyArray<T>, start: number, end?: number): Array<T>;
414+
transform(value: string, start: number, end?: number): string;
415+
transform(value: null, start: number, end?: number): null;
416+
transform(value: undefined, start: number, end?: number): undefined;
414417
}
415418

416419
export declare type Time = {

0 commit comments

Comments
 (0)
Please sign in to comment.