我正在尝试实现一组链接函数,但是不知何故我陷入了困境。
const options: any = {
chart: {
renderTo: 'container',
type: 'column',
options3d: {
enabled: true,
alpha: 15,
beta: 15,
depth: 50,
viewDistance: 25
}
},
title: {
text: 'Chart rotation demo'
},
subtitle: {
text: 'Test options by dragging the sliders below'
},
plotOptions: {
column: {
depth: 25
}
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
};
Highcharts.chart('columnChart', options);
我想在链中归档函数的类型检查。在上面的示例中,我希望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
),但到目前为止没有成功。我想知道在这种情况下还有其他方法可以提供帮助。
答案 0 :(得分:3)
删除某些功能很简单,您只需使用Omit<this, 'specialPlus'>
如果我们测试了一下就可以了,如果您调用specialPlus
,则在再次调用{ {1}},但是您可以在调用specialPlus
specialMinus
这是因为在声明interface ISpecialCalculator extends ISimpleCalculator {
specialPlus(value: number): Omit<this, 'specialPlus'>;
specialMinus(value: number): Omit<this, 'specialMinus'>;
}
declare let testCalculator: ISpecialCalculator;
testCalculator
.specialPlus(40)
// .specialPlus(40) // error ?
.specialMinus(20)
.specialPlus(40) //ok ?
.sum()
时Omit
将在this
类型的绑定上起作用,因此testCalculator
实际上将返回specialMinus
,其中仍然包含Omit<ISpecialCalculator, 'specialMinus'>
,即使我们先前已将其删除。我们想要的是让specialPlus
处理上一个函数返回的Omit
类型。如果我们使用通用类型参数为每个调用捕获this
的实际类型,并且使用该类型参数的this
方法而不是多态Omit
的方法,则可以做到这一点。
this
答案 1 :(得分:1)
specialPlus(value: number): ISimpleCalculator;
调用此函数时,您将获得一个不再具有特殊功能的简单计算器。特殊接口还应该返回this
并且应该可以正常工作:
interface ISpecialCalculator extends ISimpleCalculator {
specialPlus(value: number): this;
specialMinus(value: number): this;
}
答案 2 :(得分:1)
尝试以下操作(根据问题测试完整代码):
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...
}
}