TypeScript中具有Omit类型的函数链接

时间:2018-12-12 15:29:39

标签: typescript chaining method-chaining

比方说,我想在TypeScript中实现类型化的函数链,但是在这种情况下,调用函数会将函数从返回类型中删除。例如:

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

当我致电chain.chain1()时,我会得到Pick<Chain1 & Chain2, "execute" | "chain2"作为返回类型,这很好,因为它阻止了我两次致电chain1

但是,一旦我使用chain2函数将其链接起来,返回类型就会变成Pick<Chain1 & Chain2, "chain1" | "execute"。这将允许我再次致电chain1,这是我要防止的事情。理想情况下,编译器会抱怨Property 'chain1' does not exist on type

chain.chain1().chain2().chain1(); // I want this to return a compiler error :(

我要这样做正确吗?在TypeScript中是否可以将多个Omit类型逐渐组合在一起,以便返回类型连续地忽略属性?

1 个答案:

答案 0 :(得分:3)

我认为this的类型是在第一次检查该功能时确定的,之后再不对其进行重新评估。因此,第二次调用this的{​​{1}}仍将是原始的chain2,而不是this的返回类型。我不确定这是预期的行为还是错误,您可能想检查GitHub上的类似问题。

一种解决方法是使用将与chain1绑定的通用类型参数为任何给定函数捕获this。这将确保通过功能链的类型流正确。一个小问题是使用箭头功能无法进行键入,您将需要使用常规功能并访问this

this