带有省略类型的TypeScript中的函数链接
假设我想在TypeScript中实现一个类型化函数链,但在本例中,调用函数会从返回类型中删除该函数。例如:带有省略类型的TypeScript中的函数链接,typescript,chaining,method-chaining,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&l
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
我这样做对吗?在TypeScript中,是否可以逐步将多个省略类型组合在一起,以便返回类型连续省略属性?我认为
此
的类型是在首次检查函数时确定的,然后在之后的任何时候都不会重新计算。因此this
对于chain2
的第二次调用仍然是原始this
而不是chain1
的返回类型。我不确定这是预期的行为还是bug,您可能需要检查GitHub是否存在类似问题
一种解决方法是使用将绑定到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
类型省略=拾取;
可链接接口{
执行:()=>承诺;
}
接口Chain1扩展了可链接的{
chain1?:(this:T)=>省略;
}
接口Chain2扩展了可链接的{
chain2?:(this:T)=>省略;
}
让链:链1和链2={
执行:()=>null,
链1:函数(){
删除本条第1款;
归还这个;
},
链2:函数(){
删除本条第2款;
归还这个;
}
};
chain.chain1().chain2().execute();//使用功能链
chain.chain1().chain2().chain1().execute();//错误
使用这个
参数是个好主意。@jcalz 10x,我现在怀疑这个是谁。我本以为他的代码会工作,我猜多态这个是在函数声明时确定的,之后不会重新计算。这太完美了!我不喜欢使用输入参数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