Typescript :: 条件链接函数
Typescript :: Conditional chaining function
我正在尝试实现一组链式函数,但不知何故我卡在了这里。
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()
我想存档链中函数的类型检查。在上面的例子中,我希望 ISpecialCalculator
中的函数 specialPlus
和 specialMinus
只能使用一次,而 ISimpleCalculator
可以多次使用。我对打字稿很陌生,我一直在尝试不同的方法(高级类型(Pick
& Omit
)),但到目前为止都没有成功。我想知道在这种情况下是否还有其他方法可以提供帮助。
specialPlus(value: number): ISimpleCalculator;
当您调用此函数时,您将返回一个不再具有特殊功能的简单计算器。特殊接口也应该 return this
并且它应该工作:
interface ISpecialCalculator extends ISimpleCalculator {
specialPlus(value: number): this;
specialMinus(value: number): this;
}
删除一些函数很简单,你可以使用 Omit<this, 'specialPlus'>
如果我们测试它几乎可以工作,如果你调用 specialPlus
如果你在另一个调用后立即调用它,你会得到一个错误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
将在声明 testCalculator
时作用于 this
类型绑定,所以 specialMinus
实际上 return Omit<ISpecialCalculator, 'specialMinus'>
仍然包含 specialPlus
,即使我们之前删除了它。我们想要的是 Omit
处理由前一个函数编辑的 this
return 类型。如果我们使用泛型类型参数捕获每个调用的 this
的实际类型,并且来自此类型参数的 Omit
方法而不是来自多态 this
.
的方法,我们就可以做到这一点
interface ISimpleCalculator {
plus<TThis>(this: TThis,value: number): TThis;
minus<TThis>(this: TThis,value: number): TThis;
divide<TThis>(this: TThis,value: number): TThis;
multiply<TThis>(this: TThis,value: number): TThis;
sum(): void
}
interface ISpecialCalculator extends ISimpleCalculator {
specialPlus<TThis>(this: TThis, value: number): Omit<TThis, 'specialPlus'>;
specialMinus<TThis>(this: TThis, value: number): Omit<TThis, 'specialMinus'>;
}
declare let testCalculator: ISpecialCalculator;
testCalculator
.specialPlus(40)
// .specialPlus(40) // error
.specialMinus(20)
.plus(10)
.specialPlus(40) // also error
.plus(10)
.sum()
尝试以下(根据问题测试的完整代码):
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] 的使用,那么你可以在具体的 class 实现了 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...
}
}
我正在尝试实现一组链式函数,但不知何故我卡在了这里。
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()
我想存档链中函数的类型检查。在上面的例子中,我希望 ISpecialCalculator
中的函数 specialPlus
和 specialMinus
只能使用一次,而 ISimpleCalculator
可以多次使用。我对打字稿很陌生,我一直在尝试不同的方法(高级类型(Pick
& Omit
)),但到目前为止都没有成功。我想知道在这种情况下是否还有其他方法可以提供帮助。
specialPlus(value: number): ISimpleCalculator;
当您调用此函数时,您将返回一个不再具有特殊功能的简单计算器。特殊接口也应该 return this
并且它应该工作:
interface ISpecialCalculator extends ISimpleCalculator {
specialPlus(value: number): this;
specialMinus(value: number): this;
}
删除一些函数很简单,你可以使用 Omit<this, 'specialPlus'>
如果我们测试它几乎可以工作,如果你调用 specialPlus
如果你在另一个调用后立即调用它,你会得到一个错误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
将在声明 testCalculator
时作用于 this
类型绑定,所以 specialMinus
实际上 return Omit<ISpecialCalculator, 'specialMinus'>
仍然包含 specialPlus
,即使我们之前删除了它。我们想要的是 Omit
处理由前一个函数编辑的 this
return 类型。如果我们使用泛型类型参数捕获每个调用的 this
的实际类型,并且来自此类型参数的 Omit
方法而不是来自多态 this
.
interface ISimpleCalculator {
plus<TThis>(this: TThis,value: number): TThis;
minus<TThis>(this: TThis,value: number): TThis;
divide<TThis>(this: TThis,value: number): TThis;
multiply<TThis>(this: TThis,value: number): TThis;
sum(): void
}
interface ISpecialCalculator extends ISimpleCalculator {
specialPlus<TThis>(this: TThis, value: number): Omit<TThis, 'specialPlus'>;
specialMinus<TThis>(this: TThis, value: number): Omit<TThis, 'specialMinus'>;
}
declare let testCalculator: ISpecialCalculator;
testCalculator
.specialPlus(40)
// .specialPlus(40) // error
.specialMinus(20)
.plus(10)
.specialPlus(40) // also error
.plus(10)
.sum()
尝试以下(根据问题测试的完整代码):
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] 的使用,那么你可以在具体的 class 实现了 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...
}
}