Skip to content

(0,eval) produces TS2695 #12978

Description

@mihailik

TypeScript Version: 2.1.4

(0,eval)('var x = 10');

Expected behavior:
Compile fine.

Actual behavior:
error TS2695: Left side of comma operator is unused and has no side effects.

See also at TS Playground.

(0,eval) is a well-used convenience syntax for invoking eval with a global scope (as opposed to the scope of the caller).

One possible workaround is: (eval||null). But that's longer and most of all — hard to Google the reasoning behind. Whereas (0,eval) is easy to find a detailed explanation for.

Please make it not error.

Activity

  1. benjamingr commented on Dec 16, 2016

    @benjamingr

    (0,eval) is a hack, you can just use your own global eval like:

    const myEval = eval;
    myEval(`var x = 10`);

    I'm personally fine with TS erroring out on this. It is a really edgy case.

  2. mihailik commented on Dec 16, 2016

    @mihailik
    ContributorAuthor

    Calling something hack or edge case isn't relevant. Infinity is real proper edge case, yet it produces no error: 1+Infinity. (function(){ })() is a definite absolute hack, yet no errors pop up.

    What's relevant is the usage of a given pattern. (0,eval) is widely used, even in pretty much cutting edge libraries:

    https://github.com/systemjs/systemjs/blob/5ed69b6344e8fc1cd43bf758350b2236f57e1499/lib/global-eval.js#L96

    Widely-used well-known googlable "hacks" should not trigger errors. I think this check was added recently — I don't think it generated this noise in 2.0.6. It's a regression and may cause undue friction for migrating code from JS.

  3. benjamingr commented on Dec 16, 2016

    @benjamingr

    mihailik SystemJS is a module loader, it's meant to evaluate code so it's the one place where you might find this hack outside of transpiled code.

    I agree there is a bar here of what we want to honor or not. (function() {})() for scoping is hardly a hack in "idiomatic JS". Relying on whether or not eval is referenced directly or indirectly for defining global variables seems like a much much bigger stretch.

  4. RyanCavanaugh commented on Dec 16, 2016

    @RyanCavanaugh
    Member

    Allowing strictly eval as a special case right operand here seems fine.

  5. mihailik commented on Dec 16, 2016

    @mihailik
    ContributorAuthor

    Totally agree with eval being the only special exception here.

    Certain type of code relies on eval: binding frameworks, dynamic code transforms, loaders and so on. Indirect (0,eval) is an important feature in such cases.

    Couple more examples:

    https://github.com/knockout/knockout/blob/241c26ca82e6e4b3eaee39e3dc0a92f85bc1df0c/build/fragments/extern-pre.js#L4

    https://github.com/facebook/react/blob/c78464f8ea9a5b00ec80252d20a71a1482210e57/scripts/bench/measure.py#L24

  6. yortus commented on Dec 17, 2016

    @yortus
    Contributor

    For reference, background to current behaviour can be found in #10814 which was prompted by the scenario in #10802.

  7. aluanhaddad commented on Dec 17, 2016

    @aluanhaddad
    Contributor

    Troy Gerwien (@yortus) thanks for the providing the context. It seems a bit hand-holdy given that it's not a type level rule and that people can generally be expected to know the syntax for control flow constructs. The comma operator is definitely an easy thing to get wrong and probably something I would otherwise want to ban with a linter but not necessarily at the language level.

  8. mhegazy commented on Jan 23, 2017

    @mhegazy
    Contributor

    Using void operator disables the check, so you can use (void 0,eval)('var x = 10');

  9. added this to the milestone on Jan 24, 2017
  10. RyanCavanaugh commented on Jan 24, 2017

    @RyanCavanaugh
    Member

    Accepting PRs to allow strictly the identifier eval as the right-side comma operand without error

  11. modified the milestones: TypeScript 2.3, on Feb 27, 2017
  12. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issueHelp WantedYou can do thisSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions