Typescript 调整作为函数参数传递的对象中方法的“this”上下文

Typescript 调整作为函数参数传递的对象中方法的“this”上下文,typescript,types,casting,typescript-generics,Typescript,Types,Casting,Typescript Generics,我在将此上下文更新为作为参数传递的对象的方法时遇到问题 function decorate<T extends { [K in keyof T]: T[K] extends (this: infer This, ...args: infer Args) => infer Return ? (this: This & { abc: 10 }, ...args: Args) => Return : never; }>(objec

我在将此上下文更新为作为参数传递的对象的方法时遇到问题

function decorate<T extends {
    [K in keyof T]: T[K] extends (this: infer This, ...args: infer Args) => infer Return
        ? (this: This & { abc: 10 }, ...args: Args) => Return
        : never;
}>(object: T) {
    // @ts-ignore: just a hack to show a simple example
    object.abc = 10;
    return object;
}

decorate({
   getString() { return "abc"; },
   doSomething() {
       const str: string = this.getString(); // Property 'getString' does not exist on type '{ abc: 10; }'.(2339)
       const abc: number = this.abc;
   }
});
我试图直接使用原始对象作为上下文,但此时T仅被检测为具有未知属性的对象{}:

function decorate<T extends {
    [K in keyof T]: T[K] extends (...args: infer Args) => infer Return
        ? (this: T, ...args: Args) => Return
        : never;
}>(object: T) {
    // @ts-ignore: just a hack to show a simple example
    object.abc = 10;
    return object;
}

decorate({
   getString() { return "abc"; },
   doSomething() {
       const str: string = this.getString(); // Property 'getString' does not exist on type '{}'. (2339)
       const abc: number = this.abc; // Property 'abc' does not exist on type '{}'. (2339)
   }
});

是否有一种方法可以调整传递对象的方法的上下文,或者可能有完全不同的方法来实现类似的效果?

我认为您最好使用这种类型。这是编译器的一个特殊标记接口,允许您轻松指定这意味着什么。将对象指定给类型为ThisType的位置时,T被视为该对象中定义的任何方法/函数的类型

这样,问题的解决方案就变得非常简单:

function decorate<T>(object: T & ThisType<T & { abc: number }>) {
    return Object.assign( object, { abc:  10 });
}

decorate({
   getString() { return "abc"; },
   doSomething() {
       const str: string = this.getString(); // Property 'getString' does not exist on type '{}'. (2339)
       const abc: number = this.abc; // Property 'abc' does not exist on type '{}'. (2339)
   }
});
谢谢,我没有注意到这种类型的记号笔,它工作起来很有魅力!
function decorate<T>(object: T & ThisType<T & { abc: number }>) {
    return Object.assign( object, { abc:  10 });
}

decorate({
   getString() { return "abc"; },
   doSomething() {
       const str: string = this.getString(); // Property 'getString' does not exist on type '{}'. (2339)
       const abc: number = this.abc; // Property 'abc' does not exist on type '{}'. (2339)
   }
});