angulartypescriptoopangular2-pipe

How to overwrite / match extended CurrencyPipe method type in Angular


I am trying to reuse existing currency pipe from Angular common. Goal is to have .00 truncated when the value is round. For this I've wrote this piece of code:

/** Transform currency string and round it.  */
@Pipe({name: 'customCurrency'})
export class CustomCurrencyPipe extends CurrencyPipe implements PipeTransform {
  transform(value: number|string|null|undefined): string|null {
    if (!isValue(value)) return null;
    const valueFormat = (+value % 1 === 0) ? '1.0-0' : '1.2-2';
    return super.transform(value, 'USD', 'symbol', valueFormat);
  }
}

function isValue(value: number|string|null|undefined): value is number|string {
  return !(value == null || value === '' || value !== value);
}

if I set transform type to :any it runs no problem. However I am not allowed to use any in current environment. And if I set it to :string|null I get this error:

TS2416: Property 'transform' in type 'CustomCurrencyPipe' is not assignable to the same property in base type 'CurrencyPipe'.
  Type '(value: string | number | null | undefined) => string | null' is not assignable to type '{ (value: string | number, currencyCode?: string | undefined, display?: string | boolean | undefined, digitsInfo?: string | undefined, locale?: string | undefined): string | null; (value: null | undefined, currencyCode?: string | undefined, display?: string | ... 1 more ... | undefined, digitsInfo?: string | undefin...'.
    Type 'string | null' is not assignable to type 'null'.
      Type 'string' is not assignable to type 'null'.

7   transform(value: number|string|null|undefined): string|null {

How can I set my return type so it matches signature of extended pipe?


Solution

  • Actually there's nothing wrong with your code. Angular team introduced stricter types in version 11 where some of the pipes have overloads.

    Source: https://github.com/angular/angular/pull/37447

    Thus, this is purely a typescript compiler issue. You can get rid of it by simply implementing the overload.

    @Pipe({ name: 'customCurrency' })
    export class CustomCurrencyPipe extends CurrencyPipe implements PipeTransform {
      transform(value: number | string | null | undefined): null;
      transform(value: number | string | null | undefined): string | null {
        if (!isValue(value)) return null;
        const valueFormat = +value % 1 === 0 ? '1.0-0' : '1.2-2';
        return super.transform(value, 'USD', 'symbol', valueFormat);
      }
    }
    

    Stackblitz