繁体   English   中英

使用Omit类型在TypeScript中进行函数链接

[英]Function chaining in TypeScript with Omit types

假设我想在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" Pick<Chain1 & Chain2, "execute" | "chain2"作为返回类型,这很棒,因为它阻止我两次调用chain1

但是,只要我用chain2函数链接它,返回类型就变成Pick<Chain1 & Chain2, "chain1" | "execute" 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类型组合在一起,以便返回类型不断省略属性?

我认为对于类型this时候首先检查功能,在任何时候再重新评估,不后确定。 所以, this对于第二次调用chain2仍将是原来this不是返回类型chain1 我不确定这是预期的行为还是错误,您可能需要检查GitHub是否存在类似问题。

一种解决方法是使用泛型类型参数为任何给定函数捕获this函数,该参数将与this 这将确保通过功能链的正确类型流。 一个小问题是,分型则使用箭头功能将无法正常工作了,你将需要使用常规的功能和访问this

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;

interface Chainable {
    execute: () => Promise<void>;
}

interface Chain1 extends Chainable {
    chain1?: <T extends Chain1>(this: T) => Omit<T, 'chain1'>;
}

interface Chain2 extends Chainable {
    chain2?: <T extends Chain2>(this: T) => Omit<T, 'chain2'>;
}

let chain: Chain1 & Chain2 = {
    execute: () => null,
    chain1: function () {
        delete this.chain1;
        return this;
    },
    chain2: function ()  {
        delete this.chain2;
        return this;
    }
};

chain.chain1().chain2().execute(); // Using the function chain
chain.chain1().chain2().chain1().execute(); // error

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM