我试图从一个外部库中扩展一个类,该库包含在开始任何操作之前在输入中使用其构造函数的方法,因为它可以有多个类型。我想创建一个类,类似于它的工作,但输入是消毒。
class ParentClass {
constructor(value: ParentClass.ValueType) {
// ...
}
methodUsingConstructor(otherValue: ParentClass.ValueType) {
const x = new this.constructor(otherValue)
// do some stuff here with x ...
return result;
}
// ...
}
如果我做
class SafeParentClass extends ParentClass {
constructor(value: ParentClass.ValueType) {
// Do some input sanitizing ...
super(sanitizedValue);
}
}
我可以使用new SafeParentClass(value)
。但是,我将使用ParentClass的构造函数获取一个对象。这意味着如果我执行(new SafeParentClass(value1)).methodUsingConstructor(value2)
,那么value2
没有被清理,我会得到一个错误。
我如何创建一个SafeParentClass
,这样我就可以调用ParentClass
的方法,并且它们将有一个清理输入的构造函数?
范例:
import { Decimal } from 'decimal.js';
class SafeDecimal extends Decimal {
constructor(value: Decimal.Value) {
if (typeof value === 'string') {
super(parseFloat(value)); // will do super('NaN') if value is not parseable
} else {
super(value);
}
}
}
然后测试它
describe('safeDecimal', () => {
it('should return NaN output with invalid input', () => {
expect(new SafeDecimal('123123').add('').toString()).toEqual('NaN');
});
});
它抛出一个DecimalError
。
2条答案
按热度按时间icnyk63a1#
问题在于
decimal.js
的写法。它将each instance上的constructor
属性重写为Decimal
(而不是允许它从原型继承,这是正常的事情)。它在当前decimal.mjs
(x.constructor = Decimal;
)中的4,290行上执行此操作。它的注解说它这样做是为了隐藏继承的那个 ". which isObject
."(正常的做法是在insetad中修复继承的那个)。你可以通过重写
decimal.js
的操作来解决这个问题:然后,使用构造函数,计算示例工作(结果为
NaN
)。我没有测试过其他东西。**在正常情况下,你不需要这个。**这是必要的,因为
decimal.js
的具体编写方式。话虽如此,你可能想分叉它,并在分叉中做你认为需要做的修改。
最后,您可能需要考虑做一些比
parseFloat
更健壮的事情,因为parseFloat
将很乐意为字符串"123asdlfkjasldf"
返回123
(而抛出错误或返回NaN
可能更合理)。这里有一个答案,你可以选择各种工具来构建更健壮的东西。t98cgbkg2#
恐怕,你必须在派生类中自己实现所有的方法。如果第三方类的方法的逻辑并不完全符合您的要求,您可以创建一个派生类并将原始方法引用为
super.method(…)
。使用这种技术,您可以首先清理输入,然后将其定向到原始方法。基本上,你是这样做的:
你必须对你使用的所有方法都这样做。