Home > Mobile >  Typescript cannot reference this from static function
Typescript cannot reference this from static function

Time:07-18

According to https://github.com/microsoft/TypeScript/issues/6331 referencing this in static is perfectly legal, however, using a class like:

class ZController {
    static async b(req: RequestType, res: Response) {
            await this.a(req);
    }

    static async a(req) {
        console.log('here')
    }
}

results in:

Error: unhandledRejection: Cannot read properties of undefined (reading 'a')
TypeError: Cannot read properties of undefined (reading 'a')
    at b (/usr/src/app/controllers/z.ts:24:33)
    at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)
    at next (/usr/src/app/node_modules/express/lib/router/route.js:137:13)
    at xxx (/usr/src/app/middlewares/Auth.js:108:17)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

I am running Typescript 4.4.2.

Why is this? According to my research typescript should support this.

CodePudding user response:

Somewhere in your code your are passing an unbound copy of ZController.b. This means that when you call it, this will not be bound to ZController.

type Req = {};
type Res = {}
class ZController {
    static async b(req: Req, res: Res) {
        await this.a(req);
    }

    static async a(req: Req) {
        console.log('here')
    }
}

ZController.b({}, {}); // works fine

const zb = ZController.b; // zb is not bound to `ZController`

zb({}, {}); // so here, we see failure... this is undefined

//fix by binding back to ZController

const zb2 = ZController.b.bind(ZController);

zb2({}, {}); // works fine

// or wrapping:

const zb3 = (req: Req, res: Res) => ZController.b(req, res);

zb3({}, {}); // works fine

or just don't use this in your static methods

class ZController2 {
    static async b(req: Req, res: Res) {
        await ZController2.a(req);
    }

    static async a(req: Req) {
        console.log('here2')
    }
}

const zb4 = ZController2.b;

zb4({},{}) //works

Playground Link

  • Related