如何在 Angular 中覆盖/匹配扩展的 CurrencyPipe 方法类型
How to overwrite / match extended CurrencyPipe method type in Angular
我正在尝试重用来自 Angular common 的现有货币管道。目标是在值是四舍五入时截断 .00。为此,我写了这段代码:
/** 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);
}
如果我将转换类型设置为 :any 它运行没有问题。但是我不允许在当前环境中使用任何东西。如果我将它设置为 :string|null 我会得到这个错误:
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 {
如何设置我的 return 类型以匹配扩展管道的签名?
这是真的,因为您通过更改扩展 class 中的合同,违反了 Liskov 的 SOLID 原则。相反,您可以注入货币管道并将其用作服务
some-module.ts
...
providers: [CurrencyPipe],
....
customCurrency
@Pipe({name: 'customCurrency'})
export class CustomCurrencyPipe implements PipeTransform {
constructor(private currencyPipe: CurrencyPipe) {}
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 this.currencyPipe.transform(value, 'USD', 'symbol', valueFormat);
}
....
}
实际上你的代码没有任何问题。 Angular 团队在版本 11 中引入了更严格的类型,其中一些管道有过载。
来源:https://github.com/angular/angular/pull/37447
因此,这纯粹是打字稿编译器的问题。您可以通过简单地实现重载来摆脱它。
@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);
}
}
我正在尝试重用来自 Angular common 的现有货币管道。目标是在值是四舍五入时截断 .00。为此,我写了这段代码:
/** 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);
}
如果我将转换类型设置为 :any 它运行没有问题。但是我不允许在当前环境中使用任何东西。如果我将它设置为 :string|null 我会得到这个错误:
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 {
如何设置我的 return 类型以匹配扩展管道的签名?
这是真的,因为您通过更改扩展 class 中的合同,违反了 Liskov 的 SOLID 原则。相反,您可以注入货币管道并将其用作服务
some-module.ts
...
providers: [CurrencyPipe],
....
customCurrency
@Pipe({name: 'customCurrency'})
export class CustomCurrencyPipe implements PipeTransform {
constructor(private currencyPipe: CurrencyPipe) {}
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 this.currencyPipe.transform(value, 'USD', 'symbol', valueFormat);
}
....
}
实际上你的代码没有任何问题。 Angular 团队在版本 11 中引入了更严格的类型,其中一些管道有过载。
来源:https://github.com/angular/angular/pull/37447
因此,这纯粹是打字稿编译器的问题。您可以通过简单地实现重载来摆脱它。
@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);
}
}