Let's say I wanted to implement a typed function chain in TypeScript, but in this case, calling a function removes that function from the return type. For example:
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
interface Chainable {
execute: () => Promise<void>;
}
interface Chain1 extends Chainable {
chain1?: () => Omit<this, 'chain1'>;
}
interface Chain2 extends Chainable {
chain2?: () => Omit<this, 'chain2'>;
}
let chain: Chain1 & Chain2 = {
execute: () => null,
chain1: () => {
delete chain.chain1;
return chain;
},
chain2: () => {
delete chain.chain2;
return chain;
}
};
chain.chain1().chain2().execute(); // Using the function chain
When I call chain.chain1(), I would get Pick<Chain1 & Chain2, "execute" | "chain2" as the return type, which is great, since it prevents me from calling chain1 twice.
However, as soon as I chain it with the chain2 function, the return type becomes Pick<Chain1 & Chain2, "chain1" | "execute". This would allow me to call chain1 again, which is what I'm trying to prevent. Ideally, the compiler would complain that Property 'chain1' does not exist on type:
chain.chain1().chain2().chain1(); // I want this to return a compiler error :(
Am I going about this the right way? Is it possible in TypeScript to progressively combine multiple Omit types together, so that the return types continuously omit properties?