比方说,我想在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类型逐渐组合在一起,以便返回类型连续地忽略属性?
答案 0 :(得分:3)
我认为this
的类型是在第一次检查该功能时确定的,之后再不对其进行重新评估。因此,第二次调用this
的{{1}}仍将是原始的chain2
,而不是this
的返回类型。我不确定这是预期的行为还是错误,您可能想检查GitHub上的类似问题。
一种解决方法是使用将与chain1
绑定的通用类型参数为任何给定函数捕获this
。这将确保通过功能链的类型流正确。一个小问题是使用箭头功能无法进行键入,您将需要使用常规功能并访问this
:
this