microsoft / TypeScript

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

TS 3.7: optional chaining output is introducing a local variable #34594

Open bpasero opened 5 years ago

bpasero commented 5 years ago

TypeScript Version: 3.7.x-dev.201xxxxx

Search Terms: optional chaining

Code

function isTrue(something: { value: boolean} | undefined): boolean {
    return something?.value === true; 
}

Expected behavior: Output:

"use strict";
function isTrue(something) {
    return (something === null || something === void 0 ? void 0 : something.value) === true;
}

Actual behavior: Actual Output:

"use strict";
function isTrue(something) {
    var _a;
    return ((_a = something) === null || _a === void 0 ? void 0 : _a.value) === true;
}
MartinJohns commented 5 years ago

For simple cases this seems redundant, but for more complex cases this is necessary. In the case of properties there could be a getter with logic behind it, and in that case you wouldn't want it to be evaluated twice.

For example:

class Fubar {
    public get nested(): { value: boolean } {
        console.log("nested accessed.");
        return { value: true };
    }
}

function isTrue(something: { nested: { value: boolean } | undefined }): boolean {
    return something.nested?.value === true; 
}

isTrue(new Fubar());

Without the local variable you would get two console log statements, but with the local variable only one.

I would guess there is no special distinction whether this is necessary or not, and personally I doubt the worth of such a check.

bpasero commented 5 years ago

Yeah I was not thinking it should be changed in all cases, only for the simple ones if possible.