Reputation: 387
Can we exclude method from type when we use it in fluent api. For example: We have setup class which has step by step methods.
class Setup{
step1(){ return this;}
step2(){ return this;}
step3(){ return this;}
}
let setup = new Setup();
And now what i want achieve. First what i will use will be obviously step1 so: setup.step1(). //And after a dot i still can choose a step1 again but i want to prevent it, as I said before how can i exclude step1 to keep only step2 and step3
Upvotes: 0
Views: 117
Reputation: 2486
I think I'm close. First let's define Omit util export type Omit<A extends object, K extends string> = Pick<A, Exclude<keyof A, K>>
it will create new interface without one specific field.
then let's change type definition of step1
method from step1(): Setup
to step1(): Omit<Setup, 'step1'>
.
In that case setup1 will return Setup instance without one filed: step1
.
Unfortunately you still be able to do this:
setup.step1();
setup.step1();
but when you chain methods, you will received error
setup
.step1()
.step1(); // ERROR
because Property 'step1' does not exist on type Omit
Playground [Edited]
Upvotes: 0
Reputation: 249716
You can use Omit
to exclude the methods. The trick is to get the omitted methods to flow through the calls. Polymorphic this is not an option since it is determined when the class is created (not based on the actual call target). We can use a type parameter to infer this
based on the call target (this has to be done so since the call target may already have methods excluded)
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
class Setup {
step1<T extends Partial<Setup>>(this: T) : Omit<T, 'step1'> { return this; }
step2<T extends Partial<Setup>>(this: T) : Omit<T, 'step2'> { return this; }
step3<T extends Partial<Setup>>(this: T) : Omit<T, 'step3'> { return this; }
}
let setup = new Setup();
setup.step1().step2().step3()
setup.step1().step2().step2() //err
Also since this
might now not contain all methods, we say that T
will extends Partial<Setup>
. This makes the types workout but it will make this
hard to use inside the function so consider using something like const self = this as Setup
and using self
Upvotes: 3