Be aware that an async (in TypeScript) when not required adds extra code

Whilst aysnc/await is not formally part of the ES spec (I believe it is available when targetting es2017) we need to be aware of situations where declaring async adds code which is not required.

Specifically I came across some code where a class’s method was marked as async but without an implementation, i.e.

class Derived {
    public async doSomething(): Promise<void> {
    }
}

This compiled/transpiled with the tsconfig.json settings of the project (a React project) and will produce the following code

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class Derived {
    doSomething() {
        return __awaiter(this, void 0, void 0, function* () {
        });
    }
}

Obviously is not the intention here, i.e. to include the __awaiter code etc. What the code should have looked like is

class Derived {
    public dataBind(): Promise<void> {
        return Promise.resolve();
    }
}

which then produces JavaScript matching exactly this code, i.e.

"use strict";
class Derived {
    dataBind() {
        return Promise.resolve();
    }
}

I know this might seem a little picky, but from what I could see, for every file that includes an empty async method we get an __awaiter created, considering we use minifiers etc. to try to reduce our code size, this obviously makes a difference when code size is important.