microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.95k stars 12.48k forks source link

Async/Await generated code failing in Node 8.* #18681

Closed grofit closed 7 years ago

grofit commented 7 years ago

TypeScript Version: 2.5.2

I am facing an issue in node 8 where my async method is bombing with the error:

yield doSomethingThatRetunsPromise();
^^^^^

SyntaxError: Unexpected strict mode reserved word

After taking a look through it seems to be that all the working methods have the __awaiter added as the method body wrapper, however this one does not. The only thing that appears to be different between this and other methods that get the __awaiter is that this contains an await without a response.

I am using Node 8 as platform I am running on, and I am compiling the ts with:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2015",
    "sourceMap": true,
    "moduleResolution": "node",
    "noImplicitAny": false,
    "lib": ["es2015"]
  },
  "exclude": [
    "node_modules"
  ]
}

Here is an example bit of code that shows what happens:

Example code

private someExpressRoute = async (req: Request, res: Response) => {
    try
    {
        await doSomethingThatRetunsPromise();   // await but no return
        res.status(200).send();
    }
    catch(error)
    {
        res.status(500).send({ error: "Something went wrong" });
    }        
}

Expected behavior:

this.someExpressRoute = (req, res) => __awaiter(this, void 0, void 0, function* () { // as awaiter
    try {
        yield doSomethingThatRetunsPromise();
        res.status(200).send();
    }
    catch (error) {
        res.status(500).send({ error: "Something went wrong" });
    }
});

Actual behavior:

this.someExpressRoute = (req, res) => { // no awaiter
    try {
        yield doSomethingThatRetunsPromise();
        res.status(200).send();
    }
    catch (error) {
        res.status(500).send({ error: "Something went wrong" });
    }
};

I am not sure if the expected behaviour is correct as not entirely sure what generator syntax is valid, but as TS compiles without any errors I would assume the code should be fine, but the other methods with awaiter bit do not cause any problems.

DanielRosenwasser commented 7 years ago

Luckily you can work around this by targeting es2017 in the meantime - Node 7.6 has supported async await for a bit now.

mhegazy commented 7 years ago

@weswigham can you take a look

weswigham commented 7 years ago

I can't seem to repro this with the following:

// @target: es2015
// @module: commonjs
declare const doSomethingThatRetunsPromise: any;
class Foo {
    private someExpressRoute = async (req: Request, res: {
        status(x: number): { send: Function };
    }) => {
        try
        {
            await doSomethingThatRetunsPromise(); // await but no return
            res.status(200).send();
        }
        catch(error)
        {
            res.status(500).send({ error: "Something went wrong" });
        }
    }
}

@grofit Does this still repro for you with typesript@next? If so, can I have some more context to figure out what's going on?

mhegazy commented 7 years ago

--t es5 does it for me.

mhegazy commented 7 years ago

my bad. i can not reproduce this locally on latest either.

grofit commented 7 years ago

I was changing build config a lot so not entirely sure if it was es5 that was causing it, it seems fine at the moment and I am not sure if it was the await which caused it, but I have a version in the private npm repo with this problem, so TSC has output this at some point as I dont touch the dist folder (where it outputs to) but I cannot say for sure what caused it.

Thanks for looking though.