在作为参数传递的 function/object 中键入 "this"

Typing "this" inside a function/object passed as parameter

我正在尝试实现一个函数,该函数接受一组函数并强制它们的类型(稍后将 Function.bind-ed)。

这是我希望实现的目标:

function testSA<T>(m: T & ThisType<T>): T {
    return m;
}

const TEST = testSA({
    a() {
        this.b();
    },
    b() {
        this.tata = 4;
    },
});

但这会导致在 a()b()

中出现未类型化的 this (== any)

我还尝试解包每个函数并设置其 type 参数:

function testSA<T>(m: {
    [k in keyof T]: (this: T) => void;
}): T {
    return m as any;
}

但这会导致未类型化的 this (== unknown) 未类型化的 TEST 结果(== unknown 也是)

至少,我尝试将另一种类型设置为this,看看它是否与声明的递归性有关。对于 ThisType 方式:

function testSA<T>(m: T & ThisType<{ tata: number }>): T {
    return m;
}

它产生了完全相同的结果(我想 ThisType 不适用于作为参数传递的对象?)

但对于 this 参数方式:

function testSA<T>(m: {
    [k in keyof T]: (this: { tata: number }) => void;
}): T {
    return m as any;
}

有效,我在 b() 中得到了预期的没有错误,但在 a() 中有一个错误说 this.b 不存在.

有没有办法做到这一点 this 类型检查适用于自引用类型? (或者在我的函数集中实现类型检查的解决方法?)

总结一个回答中的评论:不是代码本身的问题,是Typescript的配置问题。正如我们在这两个游乐场中看到的那样:

所以,为了解决目前的情况,我只需要在tsconfig.json中添加"noImplicitThis": true。然后问题中的代码示例有效 as-is.

至于“为什么?”:似乎这个参数实际上改变了 TS 在函数内部计算 this 类型的方式。不过,这是目前的 undocumented 行为。