我正在尝试实现一组链接函数,但不知何故我被困在这里。
interface ISimpleCalculator {
plus(value: number): this;
minus(value: number): this;
divide(value: number): this;
multiply(value: number): this;
sum(): void
}
interface ISpecialCalculator extends ISimpleCalculator {
specialPlus(value: number): ISimpleCalculator;
specialMinus(value: number): ISimpleCalculator;
}
let testCalculator: ISpecialCalculator;
testCalculator
.plus(20)
.multiply(2)
.specialPlus(40)
.plus(20)
.minus(5)
.specialMinus(20) //<-- Error! Property 'specialMinus' does not exist on type 'ISimpleCalculator'.
.sum()
我想在链中归档函数的类型检查。在上面的示例中,我希望specialPlus
中的功能specialMinus
和ISpecialCalculator
仅使用一次,并且ISimpleCalculator
可以多次使用。我对打字稿非常了解,我一直在尝试不同的方法(高级类型(Pick
和Omit
)),但到目前为止没有成功。我想知道在这种情况下还有其他方法可以提供帮助。
specialPlus(value: number): ISimpleCalculator;
当您调用此函数时,您将得到一个不再具有特殊功能的简单计算器。特殊接口还应该返回this
,并且应该可以正常工作:
interface ISpecialCalculator extends ISimpleCalculator {
specialPlus(value: number): this;
specialMinus(value: number): this;
}
尝试以下操作(根据问题测试了完整的代码):
interface ISimpleCalculator {
plus(value: number): this
minus(value: number): this
divide(value: number): this
multiply(value: number): this
sum(): void
}
interface ISpecialCalculator extends ISimpleCalculator {
specialPlus(value: number): this
specialMinus(value: number): this
}
let testCalculator: ISpecialCalculator
testCalculator
.plus(20)
.multiply(2)
.specialPlus(40)
.plus(20)
.minus(5)
.specialMinus(20)
.sum()
如果要限制special [Plus | Minus]的用法,则可以在实现ISpecialCalculator接口的具体类中完成此操作。
下面的代码可能会给您一些想法:
class Calculator implements ISpecialCalculator {
specialPlusUsed = false
specialMinusUsed = false
specialPlus(value: number): this {
if (this.specialPlusUsed) throw new Error("SpecialPlus can be used only once!")
this.specialPlusUsed = true
// Related calculations here...
return this
}
specialMinus(value: number): this {
if (this.specialMinusUsed) throw new Error("SpecialMinus can be used only once!")
this.specialMinusUsed = true
// Related calculations here...
return this
}
plus(value: number): this {
// Related calculations here...
return this
}
minus(value: number): this {
// Related calculations here...
return this
}
divide(value: number): this {
// Related calculations here...
return this
}
multiply(value: number): this {
// Related calculations here...
return this
}
sum(): void {
// Related calculations here...
}
}
删除一些功能很简单,您可以只使用Omit<this, 'specialPlus'>
如果我们测试了一下它几乎可以正常工作,如果您调用specialPlus
,则在再次调用specialPlus
后立即调用它会出现错误。但是在调用specialMinus