Colisan
Colisan

Reputation: 243

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

I'm trying to achieve a function that takes a set of functions and force their type (they will be Function.bind-ed later).

Here's what I was hoping to achieve :

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

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

But this result in an untyped this (== any) inside both a() and b()

I also tried to unwrap each function and set its type parameter as such :

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

But this result in an untyped this (== unknown) and an untyped TEST result (== unknown too)

At least, I tried setting another type as this to see if it was to do with the recursiveness of the declaration. For the ThisType way :

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

It yielded the exact same result (I suppose that ThisType dont work on objects passed as parameters?)

But for the this-parameter way :

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

It worked, I got as expected no error in b() but an error in a() saying that this.b doesn't exist.

It there a way to do this this type checking that works with a self-referring type? (or a workaround to achieve the type checking inside my function set?)

Upvotes: 5

Views: 343

Answers (1)

Colisan
Colisan

Reputation: 243

Summarizing the comments in an answer: It's not a problem in the code itself, it's a Typescript configuration problem. As we can see in those two playgrounds:

So, to solve the current situation, I simply needed to add "noImplicitThis": true inside the tsconfig.json. Then the code sample from the question works as-is.

As to "why?": it seems like this parameter actually changes the way TS is computing the type of this inside the functions. This is currently an undocumented behavior though.

Upvotes: 1

Related Questions