feat(common): stricter types for DatePipe (#37447)

Make typing of DatePipe stricter to catch some misuses (such as passing
an Observable or an array) at compile time.

BREAKING CHANGE:
The signature of the `date` pipe now explicitly states which types are
accepted. This should only cause issues in corner cases, as any other
values would result in runtime exceptions.

PR Close #37447
This commit is contained in:
Andrea Canciani 2020-03-27 11:35:08 +01:00 committed by Alex Rickabaugh
parent 5f815c0565
commit daf8b7f100
5 changed files with 23 additions and 5 deletions

View File

@ -18,7 +18,9 @@ export declare class CurrencyPipe implements PipeTransform {
export declare class DatePipe implements PipeTransform { export declare class DatePipe implements PipeTransform {
constructor(locale: string); constructor(locale: string);
transform(value: any, format?: string, timezone?: string, locale?: string): string | null; transform(value: Date | string | number, format?: string, timezone?: string, locale?: string): string | null;
transform(value: null | undefined, format?: string, timezone?: string, locale?: string): null;
transform(value: Date | string | number | null | undefined, format?: string, timezone?: string, locale?: string): string | null;
} }
export declare class DecimalPipe implements PipeTransform { export declare class DecimalPipe implements PipeTransform {

View File

@ -171,7 +171,15 @@ export class DatePipe implements PipeTransform {
* See [Setting your app locale](guide/i18n#setting-up-the-locale-of-your-app). * See [Setting your app locale](guide/i18n#setting-up-the-locale-of-your-app).
* @returns A date string in the desired format. * @returns A date string in the desired format.
*/ */
transform(value: any, format = 'mediumDate', timezone?: string, locale?: string): string|null { transform(value: Date|string|number, format?: string, timezone?: string, locale?: string): string
|null;
transform(value: null|undefined, format?: string, timezone?: string, locale?: string): null;
transform(
value: Date|string|number|null|undefined, format?: string, timezone?: string,
locale?: string): string|null;
transform(
value: Date|string|number|null|undefined, format = 'mediumDate', timezone?: string,
locale?: string): string|null {
if (value == null || value === '' || value !== value) return null; if (value == null || value === '' || value !== value) return null;
try { try {

View File

@ -59,12 +59,20 @@ import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_refle
expect(pipe.transform(Number.NaN)).toEqual(null); expect(pipe.transform(Number.NaN)).toEqual(null);
}); });
it('should return null for null', () => {
expect(pipe.transform(null)).toEqual(null);
});
it('should return null for undefined', () => {
expect(pipe.transform(undefined)).toEqual(null);
});
it('should support ISO string without time', () => { it('should support ISO string without time', () => {
expect(() => pipe.transform(isoStringWithoutTime)).not.toThrow(); expect(() => pipe.transform(isoStringWithoutTime)).not.toThrow();
}); });
it('should not support other objects', () => { it('should not support other objects', () => {
expect(() => pipe.transform({})).toThrowError(/InvalidPipeArgument/); expect(() => pipe.transform({} as any)).toThrowError(/InvalidPipeArgument/);
}); });
}); });

View File

@ -274,7 +274,7 @@ describe('definitions', () => {
expect(textSpan).toEqual(marker); expect(textSpan).toEqual(marker);
expect(definitions).toBeDefined(); expect(definitions).toBeDefined();
expect(definitions!.length).toBe(1); expect(definitions!.length).toBe(3);
const refFileName = '/node_modules/@angular/common/common.d.ts'; const refFileName = '/node_modules/@angular/common/common.d.ts';
for (const def of definitions!) { for (const def of definitions!) {

View File

@ -211,7 +211,7 @@ describe('hover', () => {
expect(textSpan).toEqual(marker); expect(textSpan).toEqual(marker);
expect(toText(displayParts)) expect(toText(displayParts))
.toBe( .toBe(
'(pipe) date: (value: any, format?: string | undefined, timezone?: string | undefined, locale?: string | undefined) => string | null'); '(pipe) date: { (value: string | number | Date, format?: string | undefined, timezone?: string | undefined, locale?: string | undefined): string | null; (value: null | undefined, format?: string | undefined, timezone?: string | undefined, locale?: string | undefined): null; (value: string | ... 3 more ... | undefined, format?: st...');
}); });
it('should work for the $any() cast function', () => { it('should work for the $any() cast function', () => {