Typescript ::条件链接函数

问题描述 投票:3回答:3

我正在尝试实现一组链接函数,但不知何故我被困在这里。

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中的功能specialMinusISpecialCalculator仅使用一次,并且ISimpleCalculator可以多次使用。我对打字稿非常了解,我一直在尝试不同的方法(高级类型(PickOmit)),但到目前为止没有成功。我想知道在这种情况下还有其他方法可以提供帮助。

typescript chaining
3个回答
1
投票
specialPlus(value: number): ISimpleCalculator;

当您调用此函数时,您将得到一个不再具有特殊功能的简单计算器。特殊接口还应该返回this,并且应该可以正常工作:

interface ISpecialCalculator extends ISimpleCalculator {  
   specialPlus(value: number): this;
   specialMinus(value: number): this;
}

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...
  }
}

1
投票

删除一些功能很简单,您可以只使用Omit<this, 'specialPlus'>如果我们测试了一下它几乎可以正常工作,如果您调用specialPlus,则在再次调用specialPlus后立即调用它会出现错误。但是在调用specialMinus

© www.soinside.com 2019 - 2024. All rights reserved.