Typescript :: Conditional chaining function
Removing the some functions is simple, you can just use Omit<this, 'specialPlus'>
If we test this it almost works, if you call specialPlus
you will get an error if you call it immediately after another call to specialPlus
, you can however call it after a call to 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()
Playground Link
This is because Omit
will work on the this
type bound when testCalculator
is declared, so specialMinus
will return in fact Omit<ISpecialCalculator, 'specialMinus'>
which will still contain specialPlus
even though we previously removed it. What we want is for Omit
to work on the type of this
returned by the previous function. We can do this if we capture the actual type of this
for each call using a generic type parameter, and Omit
methods from this type parameter not from polymorphic 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()
Playground Link